专业技术 · 导游
扩展和定制集成
使用任何框架构建一个普通的HTML/JavaScript页面. SelSup将其嵌入到iframe中;它不会执行您的React代码在柜内.
使用任何框架构建一个普通的HTML/JavaScript页面. SelSup将其嵌入到iframe中;它不会执行您的React代码在柜内.
应用程序开发人员和技术合作伙伴1
选择集成类型
- 1
外部后端服务
对于 ERP,网店,WMS,BI等同步功能,最好.该代币留在服务器上,数据通过API和网关移动.
- 2
柜子iframe板
使用任何框架构建一个普通的HTML/JavaScript页面. SelSup将其嵌入到iframe中;它不会执行您的React代码在柜内.
- 3
后端模块 SelSup
需要参与共享SelSup背景流程的深入市场或交付集成.
首先实现一个完整的工作流程及其可观察性. 调整后添加大量进口,UI和更多事件类型是稳定的.
2
外部应用架构
存储代币在秘密管理器中,只从后端调用SelSup. 浏览器应用程序应该与API交谈,并且永远不会接收SelSup代币.
隔离SelSup适配器,工作队列和域名模型.
对于进来的事件使用收件箱和出发的变更,使用输入箱.
SelSup webhook → inbox → domain worker → ERP/WMS
ERP/WMS change → outbox → SelSup API → reconciliation
3
柜子iframe板
使用任何框架构建一个普通的HTML/JavaScript页面. SelSup将其嵌入到iframe中;它不会执行您的React代码在柜内.
设置一个独立的HTTPS网站,该网站与柜台没有 Cookie域名. 打开集成 → 我的扩展 → 添加扩展,选择名称,图标,URL,菜单部分和位置. 保存一个没有权限的私人面板,然后只启用所需的权限. 存储发布需要SelSup审查.
4
服务器侧集成模块
交付服务通常包括代币,卡片,价格,股票,订单和背景状态更新.
本模块改变了主要SelSup后端,并遵循其审查,测试,本地化和发布过程. 在实施之前,同意接口和数据界限.
将外部API故障转换为稳定的ApplicationError值和撤销或无效的外部代币,根据后端项目规则转换成AccessException.
没有添加市场特定的领域到共享实体. 保持原始合同的集成DTO和地图它们在边界.
5
释放和运行
- 1
创建测试帐户
根据客户生产数据,单独测试代币,仓库,产品和订单.
- 2
增加可观测性
追踪排队延迟,代码错误,重复试数,和差.
- 3
计划合同迁移
在过渡期间支持旧字段,并在禁用旧格式之前部署消费者.
- 4
文件断开连接
用户必须知道如何撤销代币,删除网络链接,
6
产品和订单单
选择菜单页面 (MENU_PAGE),产品卡卡卡 (PRODUCT_TAB) 或订单卡 (ORDER_TAB).菜单部分和位置仅适用于MENU_PAGE. 卡需要存储一个具有ID的实体.
7
文本和权限
只有授予的语境字段才会共享.USER提供user.id和user.locale;CLIENT提供client.id;ORGANIZATION提供可访问的组织ID和名称. PRODUCT单独授予产品卡上的 product.modelId;ORDER授予订单上的 order.id.id是完全的记录,联系人,密码和代币除外.这些是已开放的页面的标识符,而不是您的后端的访问证明.
{
"type": "selsup.extension.context",
"version": 1,
"context": {
"version": 1,
"extensionId": "example-extension-id",
"placement": "MENU_PAGE",
"user": {"id": 101, "locale": "ru"},
"client": {"id": 202},
"organizations": [{"id": 303, "name": "Demo"}]
}
}
[
{
"version": 1,
"extensionId": "example",
"placement": "PRODUCT_TAB",
"apiMethods": [],
"product": {
"modelId": 404
}
},
{
"version": 1,
"extensionId": "example",
"placement": "ORDER_TAB",
"apiMethods": [],
"order": {
"id": 505
}
}
]
8
邮件v1消息
查看事件.起源,事件.来源 ===窗户.父母,消息类型,版本和结构. 连接和请求文本即可更新. SelSup重新检查访问并将频繁的请求合并.永远不要在URL,面板 localStorage或消息中传输代币.
const allowedOrigins = new Set(['https://your-cabinet.example.com']);
window.addEventListener('message', (event) => {
if (event.source !== window.parent || !allowedOrigins.has(event.origin)) return;
const message = event.data;
if (!message || message.type !== 'selsup.extension.context' || message.version !== 1) return;
const context = message.context;
if (!context || context.version !== 1 || !['MENU_PAGE', 'PRODUCT_TAB', 'ORDER_TAB'].includes(context.placement)) return;
// The complete sample also validates fields and strips unknown properties.
document.querySelector('#context').textContent = JSON.stringify(context, null, 2);
});
for (const origin of allowedOrigins) {
window.parent.postMessage({type: 'selsup.extension.ready', version: 1}, origin);
}
// Refresh after connecting: use the validated origin, never "*".
window.parent.postMessage({type: 'selsup.extension.request-context', version: 1},
'https://your-cabinet.example.com');
9
通过iframe桥API
编者在扩展设置中声明所需的方法.每个安装客户端都明确授予该声明中的方法. API访问默认不允许任何,包括现有安装.更改请求列表需要再次审查;安装的副本从未自动获得新的权限.
服务器使用 SelSupFront 服务只使用以下方法,使用当前员工的权限.现有的服务器访问控制仍然适用.客户端服务和 authService 完全禁止;此列表之外的所有方法也被拒绝.应用程序无法提供URL,标题,代币或任意的Axios配置.服务器检查当前的安装和其补贴在实际API请求上.
API 补助是独立于文本权限. context.apiMethods列出授予的方法. 补贴适用于员工访问范围内的整个内方法,而不是仅仅在当前选项表中的实体.结果只包含文档化字段,从来没有Axios对象或凭证.
飞行时的请求,每秒最多一次启动.最后的256个请求ID免受重复保护.主机错误:ACCESS_DENIED,INVALID_REQUEST, RATE_LIMITED,EDUPLICATE_REQUEST,EREQUEST_FAILED.SDK错误还包括NOT_CONNECTED,DISCONNECTED和 TIMEOUT (20秒).永远不要自动重新尝试突变:error,时间过关或iframe关闭并不意味着操作已被推迟.
tagService.findTags {query?, page?, limit?} => {rows: [{id, name}]}
tagService.createTag {name} => {id, name}
tagService.updateTag {id, name} => {id, name}
tagService.deleteTag {id} => null
productService.updateFavourite {id, favourite} => null
id: positive safe integer; updateFavourite.id = product.modelId
favourite: boolean
name: 1..100 characters (trimmed); query: 0..100 characters
page: 1..10000, default 1; limit: 1..100, default 30
{
"type": "selsup.extension.api-request",
"version": 1,
"requestId": "request-1",
"method": "tagService.createTag",
"params": {
"name": "Demo"
}
}
{
"type": "selsup.extension.api-response",
"version": 1,
"requestId": "request-1",
"ok": true,
"result": {
"id": 1,
"name": "Demo"
}
}
// connection = connectExtension(...) from selsup-extension.js
// Run from a button click after receiving context.apiMethods.
const tag = await connection.callApi('tagService.createTag', {name: 'Demo'});
console.log(tag.id, tag.name);
10
应用程序和托管
样本可以复制到一个独立的 GitHub 存储库.使用 Node.js 22+, npm 测试和 npm启动运行测试以及没有 API 密钥或实际数据的本地模拟柜.配置config.js,并部署五个静态文件到 HTTPS 托管.下面链接的档案下载,并复制其内容到 GitHub 的存储室.
cd selsup-extension-example
npm test
npm start
# Mock host: http://localhost:4174/
# Panel: http://127.0.0.1:4173/
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self'; connect-src 'none'; form-action 'none'; base-uri 'none'; frame-ancestors https://your-cabinet.example.com
Referrer-Policy: no-referrer
X-Content-Type-Options: nosniff
https://api.selsup.ru/assets/examples/selsup-extension-example.zip
11
安全边界
沙盒阻止表格,弹出窗口,下载,顶级导航和敏感浏览器API.面板来源显示在iframe以上.扩展器绝不能要求SelSup密码.其网站仍然可以看到访问者IP,保留或转发给它提供的数据.审查不能结在外部URL上提供的代码.只允许必要的权限.
SelSup本身允许iframe桥接;cookies和代币从来没有进入应用程序.您的自己的后端仍然需要自己的身份验证:文本不证明身份.只在服务器上保存长期的SelSup代币.完全订购/product记录和内线卡块不支持.