AI盒绘开放平台开发者中心
欢迎接入 AI盒绘开放平台!我们为第三方合作企业系统提供标准、安全、即插即用的 AI 包装设计集成方案。您的终端用户可凭短时 Ticket 免登直达全功能设计器,设计完成后通过 Webhook 文件流将高清成品与业务参数回传至贵司系统,实现物理强隔离的一对一业务闭环。
企业数据物理隔离
多租户物理隔离体系,合作方用户、素材与设计工程完全独立归档,保障企业资产私密与安全。
动态票据免登认证
服务端安全加签申请短时凭据(Ticket),5分钟有效即焚,保障终端用户无感进入设计器,无长期凭据泄露风险。
成果 Webhook 异步直推
用户点击“完成编辑”,合成的高清图像文件流与第三方透传业务参数(extra)原样回调推送至合作方系统。
★ 3 步极速接入指南 (Quick Start)
清晰简明的标准集成路径。第三方开发者仅需关注三个动作,即可完成端到端闭环对接。
服务端加签换票
贵司服务端用 AppSecret 计算 HMAC-SHA256 签名,调用开放接口换取 5 分钟有效的一次性 ticket。
02 接入环境矩阵与沙箱凭据 (Environment Matrix)
提供完备的双环境隔离机制。开发者在沙箱联调通过后,只需替换 Base URL 与正式企业凭据即可平滑上线。
测试联调环境 (Staging / Sandbox)
供第三方开发者进行接口签名加签与完整业务链路联调
正式生产环境 (Production)
面向第三方企业正式上线业务流量,强租户物理隔离
03 申请免登票据接口 (Ticket Issue API)
避免在前端 URL 中暴露长期身份凭据。合作方服务端通过 AppSecret 离线加签,按需预先申请 5 分钟有效的一次性 Ticket。
将参与签名的键值对按 Key 字典序升序排列(过滤空值),用 & 拼接为待签名串(格式如 key1=value1&key2=value2...);使用平台分配的 AppSecret 作为密钥进行 HMAC-SHA256 运算,输出 64 位小写十六进制字符串放入请求头 X-Open-Signature。
appKey=partner_demo_key&externalUserId=corp_u_10086&nickname=张经理·高级包装师&nonce=a8f9c2d1e0b34567×tamp=1789718400
partner_demo_secret_2026 计算 HMAC-SHA256 十六进制签名结果:
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
/**
* 原生 Java 实现 HMAC-SHA256 签名,输出 64 位小写十六进制字符串
* @param stringToSign 字典序待签名串
* @param appSecret 平台分配的应用密钥 (测试环境为: partner_demo_secret_2026)
*/
public static String signHmacSha256(String stringToSign, String appSecret) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
// 此处的 appSecret 即为平台为合作方分配的企业私钥 (保密不参与网络传输)
mac.init(new SecretKeySpec(appSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
byte[] hmacBytes = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
StringBuilder hex = new StringBuilder();
for (byte b : hmacBytes) {
hex.append(String.format("%02x", b));
}
return hex.toString();
}
// === 测试调用实测示例 (带入测试私钥) ===
// String appSecret = "partner_demo_secret_2026";
// String stringToSign = "appKey=partner_demo_key&externalUserId=corp_u_10086&nickname=张经理·高级包装师&nonce=a8f9c2d1e0b34567×tamp=1789718400";
// String signature = signHmacSha256(stringToSign, appSecret);
// 打印输出: 62e5997f8a61b2c2fd177c1488753ec75a05b3de9a6c04dbe4a3af21b5818322
const crypto = require('crypto');
/**
* 原生 Node.js 实现 HMAC-SHA256 签名,输出 64 位小写十六进制字符串
* @param {string} stringToSign 字典序待签名串
* @param {string} appSecret 平台分配的企业私钥 (测试环境: partner_demo_secret_2026)
*/
function signHmacSha256(stringToSign, appSecret = 'partner_demo_secret_2026') {
return crypto.createHmac('sha256', appSecret)
.update(stringToSign, 'utf8')
.digest('hex');
}
// === 测试调用实测示例 (带入测试私钥) ===
// const appSecret = 'partner_demo_secret_2026';
// const stringToSign = 'appKey=partner_demo_key&externalUserId=corp_u_10086&nickname=张经理·高级包装师&nonce=a8f9c2d1e0b34567×tamp=1789718400';
// console.log(signHmacSha256(stringToSign, appSecret));
// 打印输出: 62e5997f8a61b2c2fd177c1488753ec75a05b3de9a6c04dbe4a3af21b5818322
import hmac
import hashlib
def sign_hmac_sha256(string_to_sign: str, app_secret: str = "partner_demo_secret_2026") -> str:
"""
原生 Python 实现 HMAC-SHA256 签名,输出 64 位小写十六进制字符串
:param string_to_sign: 字典序待签名串
:param app_secret: 平台分配的企业私钥 (测试环境: partner_demo_secret_2026)
"""
return hmac.new(
app_secret.encode('utf-8'),
string_to_sign.encode('utf-8'),
hashlib.sha256
).hexdigest()
# === 测试调用实测示例 (带入测试私钥) ===
# app_secret = "partner_demo_secret_2026"
# string_to_sign = "appKey=partner_demo_key&externalUserId=corp_u_10086&nickname=张经理·高级包装师&nonce=a8f9c2d1e0b34567×tamp=1789718400"
# print(sign_hmac_sha256(string_to_sign, app_secret))
# 打印输出: 62e5997f8a61b2c2fd177c1488753ec75a05b3de9a6c04dbe4a3af21b5818322
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
)
// SignHmacSha256 原生 Go 实现 HMAC-SHA256 签名,输出 64 位小写十六进制字符串
// appSecret: 平台分配的企业私钥 (测试环境为: partner_demo_secret_2026)
func SignHmacSha256(stringToSign, appSecret string) string {
mac := hmac.New(sha256.New, []byte(appSecret))
mac.Write([]byte(stringToSign))
return hex.EncodeToString(mac.Sum(nil))
}
// === 测试调用实测示例 (带入测试私钥) ===
// const appSecret = "partner_demo_secret_2026"
// const stringToSign = "appKey=partner_demo_key&externalUserId=corp_u_10086&nickname=张经理·高级包装师&nonce=a8f9c2d1e0b34567×tamp=1789718400"
// signature := SignHmacSha256(stringToSign, appSecret)
// fmt.Println(signature) // 62e5997f8a61b2c2fd177c1488753ec75a05b3de9a6c04dbe4a3af21b5818322
<?php
/**
* 原生 PHP 实现 HMAC-SHA256 签名,输出 64 位小写十六进制字符串
* @param string $stringToSign 字典序待签名串
* @param string $appSecret 平台分配的企业私钥 (测试环境为: partner_demo_secret_2026)
*/
function signHmacSha256($stringToSign, $appSecret = 'partner_demo_secret_2026') {
return hash_hmac('sha256', $stringToSign, $appSecret);
}
// === 测试调用实测示例 (带入测试私钥) ===
// $appSecret = 'partner_demo_secret_2026';
// $stringToSign = 'appKey=partner_demo_key&externalUserId=corp_u_10086&nickname=张经理·高级包装师&nonce=a8f9c2d1e0b34567×tamp=1789718400';
// echo signHmacSha256($stringToSign, $appSecret);
// 打印输出: 62e5997f8a61b2c2fd177c1488753ec75a05b3de9a6c04dbe4a3af21b5818322
?>
| Header Name | 示例值 | 说明 |
|---|---|---|
| Content-Type | application/json | JSON 报文格式 |
| X-Open-App-Key | partner_demo_key | 平台分配的企业应用唯一标识 |
| X-Open-Timestamp | 1789718400 | 当前 UNIX 秒级时间戳 (防过期重放,容差 ±300s) |
| X-Open-Nonce | a8f9c2d1e0b34567 | 16 位以上高强度随机字符串 (防重放) |
| X-Open-Signature | 62e5997f8a61b2c2fd177c1488753ec75a05b3de9a6c04dbe4a3af21b5818322 | HMAC-SHA256 计算出的十六进制签名摘要 (与待签名串严格对应) |
{
"externalUserId": "corp_u_10086", // 【必填】贵司系统的用户唯一标识 (进行物理隔离归档)
"nickname": "张经理·高级包装师" // 【可选】用户展示昵称
}
{
"code": 200,
"message": "success",
"data": {
"ticket": "8c3b7f1e4a9d4e5f8a1c2b3d4e5f6a7b", // 5分钟有效一次性免登 Ticket
"expiresIn": 300 // 有效期 (秒)
}
}
04 端到端完整时序交互图
直观呈现第三方系统、开放平台与终端用户浏览器之间的交互流转全过程。
[第三方服务端] [AI盒绘开放平台] [终端用户浏览器] [三方 Webhook 接收端]
│ │ │ │
│ 1. 签名计算 (HMAC-SHA256) │ │ │
│ 2. POST /open/auth/ticket│ │ │
├─────────────────────────►│ │ │
│ │ 3. 校验签名与时间戳 │ │
│ │ 4. 生成 5min 即焚 Ticket │ │
│ 5. 返回 Ticket │ │ │
│◄─────────────────────────┤ │ │
│ │ │ │
│ 6. 拼装设计器 URL (携带 ticket, image_url, extra 等) │ │
├──────────────────────────────────────────────────────►│ │
│ │ │ │
│ │ │ 7. 打开专用设计器 URL │
│ │ 8. 校验 Ticket 有效性 │ │
│ │◄──────────────────────────┤ │
│ │ 9. 即时消耗票据并载入画布 │ │
│ ├──────────────────────────►│ │
│ │ │ │
│ │ │ 10. 用户在画布进行设计 │
│ │ │ 11. 点击“完成编辑” │
│ │ 12. POST multipart/form-data 直推高清成品文件流 │
│ ├─────────────────────────────────────────────────────►│
│ │ │ │ 13. 本地存储成品
│ │ │ │ 14. 关联 extra 业务参数
│ │ 15. 返回 HTTP 200 OK 确认接收 │
│ │◄─────────────────────────────────────────────────────┤
│ │ │ │
│ │ │ 16. 提示完成并关闭设计器 │
05 唤起设计器 URL 规范 (URL Parameters)
获得 Ticket 凭据后,拼接对应环境的设计器 Base URL,在浏览器新标签页或弹窗中打开即可直接进入工作台画布。
| 参数名 (Key) | 类型 | 是否必填 | 说明与示例 |
|---|---|---|---|
| ticket | String | 必填 | 由贵司服务端提前调接口获取的一次性免登凭据。平台校验通过后即刻失效,具有高等级防重放保护。 |
| image_url | String (URL) | 推荐 |
待编辑的原素材底图远程 HTTP/HTTPS 地址。必须进行标准 encodeURIComponent 编码,设计器打开后自动拉取并铺设至画布。
|
| external_project_id | String | 推荐 |
贵司业务系统的设计任务/订单/素材唯一标识(如 order_item_9988)。Webhook 回调保存时原样携带,便于贵司精准关联成果。
|
| external_user_id | String | 推荐 |
贵司系统内部的用户唯一标识(如 corp_u_10086)。
|
| webhook_url | String (URL) | 可选 |
本次编辑保存时动态直推接收的 Webhook 回调地址(优先于平台预设配置)。需 encodeURIComponent。
|
| extra | String | 可选 |
第三方自定义业务透传参数(如生产批次号、审批单号或序列化 JSON,需 encodeURIComponent)。在设计生命周期全程维持,Webhook 回调时原样回传。
|
| title | String | 可选 | 设计项目的初始标题(如“2026月饼礼盒包装正面”)。 |
| source | String | 可选 |
渠道来源标识(如 open_platform)。
|
https://test-editor.1packify.com/aidesign/editor?ticket=8c3b7f1e4a9d4e5f8a1c2b3d4e5f6a7b&external_user_id=u_10086&external_project_id=proj_box_01&extra=batch_2026_09&image_url=https%3A%2F%2Fopen-demo.1packify.com%2Fmaterials%2Fbox.jpg&title=%E6%96%B0%E5%8C%85%E8%A3%85%E8%AE%BE%E8%AE%A1
https://editor.1packify.com/aidesign/editor?ticket=8c3b7f1e4a9d4e5f8a1c2b3d4e5f6a7b&external_user_id=corp_user_99&external_project_id=order_item_88&extra=dept_VIP&image_url=https%3A%2F%2Fcdn.your-company.com%2Fpack_front.png&title=%E9%AB%98%E6%A1%A3%E7%A4%BC%E7%9B%92%E5%AE%9A%E5%88%B6
06 完成编辑 Webhook 接收规范 (Webhook Contract)
用户在设计器中完成创作后,点击右上角“导出”->“完成编辑”。系统将直接合成高分辨率图像二进制文件流,POST 推送到指定的 Webhook 回调接口。
multipart/form-data
| 表单字段名 (Key) | 类型 | 说明 |
|---|---|---|
| file | Binary File (Blob) | 导出生成的合成图像二进制文件流 (PNG/JPEG 高清原图) |
| externalProjectId | String | 原样透传第三方传入的工程/订单 ID,用于精准入库归档 |
| externalUserId | String | 原样透传第三方传入的用户 ID |
| extra | String | 原样透传第三方传入的自定义透传数据(批次、审批号等) |
| title | String | 用户保存时的设计标题 |
200 OK 并在 Body 中返回形如 {"code":200,"message":"success"} 的响应报文。
07 多语言实战示例代码 (SDK & Code Examples)
默认引用测试沙箱环境与公开凭证。复制代码至本地项目,无需修改即可 1 秒调通加签换票与 Webhook 接收。
// ========================================================
// 1. 服务端 HMAC-SHA256 加签并申请 Ticket (完整可直接运行)
// ========================================================
public String getOpenEditorTicket(String externalUserId, String nickname) throws Exception {
// 【环境配置】沙箱测试环境基准地址与凭证 (上线生产替换为生产环境及专属凭证)
final String API_BASE_URL = "https://test-open.1packify.com/api";
final String APP_KEY = "partner_demo_key";
final String APP_SECRET = "partner_demo_secret_2026"; // 离线保密密钥
long timestamp = System.currentTimeMillis() / 1000;
String nonce = UUID.randomUUID().toString().replace("-", "").substring(0, 16);
// 1.1 参数字典序升序拼接待签名串
Map<String, String> params = new TreeMap<>();
params.put("appKey", APP_KEY);
params.put("timestamp", String.valueOf(timestamp));
params.put("nonce", nonce);
params.put("externalUserId", externalUserId);
if (nickname != null && !nickname.isEmpty()) {
params.put("nickname", nickname);
}
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
if (sb.length() > 0) sb.append("&");
sb.append(entry.getKey()).append("=").append(entry.getValue());
}
String stringToSign = sb.toString();
// 1.2 计算 HMAC-SHA256 签名 (64位 Hex 小写)
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(APP_SECRET.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
byte[] hmacBytes = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
StringBuilder hex = new StringBuilder();
for (byte b : hmacBytes) {
hex.append(String.format("%02x", b));
}
String signature = hex.toString();
// 1.3 携带请求头发送 POST 请求
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("X-Open-App-Key", APP_KEY);
headers.set("X-Open-Timestamp", String.valueOf(timestamp));
headers.set("X-Open-Nonce", nonce);
headers.set("X-Open-Signature", signature);
Map<String, Object> body = new HashMap<>();
body.put("externalUserId", externalUserId);
body.put("nickname", nickname);
HttpEntity<Map<String, Object>> entity = new HttpEntity<>(body, headers);
ResponseEntity<Map> resp = restTemplate.postForEntity(
API_BASE_URL + "/open/auth/ticket", entity, Map.class);
Map data = (Map) resp.getBody().get("data");
return (String) data.get("ticket");
}
// ========================================================
// 2. 接收完成编辑 Webhook 文件流 (Spring Boot Controller)
// ========================================================
@PostMapping("/api/webhook/aidesign/handleSave")
public ResponseEntity<Map<String, Object>> handleSave(
@RequestParam("file") MultipartFile file,
@RequestParam("externalProjectId") String externalProjectId,
@RequestParam(value = "externalUserId", required = false) String externalUserId,
@RequestParam(value = "extra", required = false) String extra,
@RequestParam(value = "title", required = false) String title) throws IOException {
// 依据外部工程 ID 业务归档保存文件
File dest = new File("/data/designs/" + externalProjectId + "_" + file.getOriginalFilename());
file.transferTo(dest);
return ResponseEntity.ok(Collections.singletonMap("code", 200));
}
08 在线参数生成调试台 (Interactive Playground)
选择目标环境并输入联调参数,即时生成符合编码标准的完整跳转 URL,并可一键进入设计器进行真实联调体验。