构建 · 移动端试穿

为 iOS 或 Android 应用添加虚拟试穿功能

一句话总结

将 Photta API 密钥保留在后端;暴露一个代理 endpoint(/mobile/try-on),接收商品图片和模特 ID,转发至 /api/v1/tryon/apparel,将 generation ID 与用户关联存储,并暴露一个状态 endpoint 供移动端每 3 秒轮询一次,直到图片生成完毕。手机端完全感知不到 Photta 密钥的存在。

  • Credits: 2K 分辨率 5 credits · 4K 分辨率 6 credits
  • 常规耗时: 1.5–4 min
  • 处理方式: 异步,轮询

本页所有数据均来自 Photta API 文档 · 已验证

设备永远不要直接与 Photta 通信——它只与你的后端通信,再由你的后端与 Photta 通信。这层边界能确保 API 密钥不暴露在用户的手机上,让你自主掌控 rate limit,并保证应用能顺利通过各大应用商店的审核。

RESPONSE=$(curl -s -X POST https://api.photta.app/api/v1/tryon/apparel \
  -H "Authorization: Bearer $PHOTTA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "product_type": "top",
  "product_images": [
    "https://cdn.yourstore.com/products/shirt-front.jpg"
  ],
  "product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg",
  "product_category": "t_shirt",
  "mannequin_id": "mnk_f3a9b1",
  "pose_id": "pose_c2d4e5",
  "background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg",
  "lock_background": true,
  "resolution": "2K",
  "aspect_ratio": "3:4",
  "body_size": "M",
  "expression": "neutral",
  "user_instruction": "Keep the collar pattern crisp and centered."
}')
ID=$(echo "$RESPONSE" | jq -r '.data.id')

工作原理

设备、后端、Photta——三层架构,统一链路

在首次提交 App Store 审核前,你需要明确的 5 个关键决策。

  1. 步骤 1

    将密钥保留在服务器端

    切勿将 Photta 密钥打包进应用二进制文件、info.plist、AndroidManifest 或任何构建期环境变量文件中——反编译二进制文件轻而易举,密钥必然泄露。你的后端是存放密钥的唯一安全位置。

  2. 步骤 2

    设计清晰的代理 endpoint

    向应用暴露 /mobile/try-on。使用你自己的用户会话进行请求鉴权——不要通过代理传递原始 API 密钥。随后由代理代表该已鉴权用户调用 Photta。

  3. 步骤 3

    在数据库中镜像 Photta 的任务状态

    当 Photta 返回 generation ID 时,在你自己的 jobs 表中插入一行记录,并以 user_id 作为键。移动端轮询的是你自己的 /mobile/try-on/:id——而不是 Photta 的——这样 rate limit 仅受你自己的套餐方案限制,与具体用户的设备无关。

  4. 步骤 4

    缓存结果 URL

    当 Photta 返回 completed 状态时,将 output_url 写入你的 jobs 记录行,并可选择将文件字节流转存至你自己的 CDN。移动端用户按 MB 消耗流量——不要在商详页(PDP)的整个生命周期内一直直链 Photta CDN。

  5. 步骤 5

    优雅处理离线状态

    移动网络在轮询过程中可能随时中断。应展示“正在重试”状态而非直接抛出硬报错,采用指数退避机制进行重试,并在本地持久化保存 job ID,以便在冷启动时能无缝恢复上次中断的会话。

集成的三个层级

App 契约、后端代理、客户端轮询——精准契合你所需的架构边界。

// Never ship your PHOTTA_API_KEY to the device. The mobile app
// calls YOUR API; your API calls Photta. Simple, safe, billable.
POST /mobile/try-on
{
  "productImageUrl": "...",
  "mannequinId": "...",
  "poseId": "..."
}
// → returns { jobId } immediately
const res = await fetch("https://api.photta.app/api/v1/tryon/apparel", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "product_type": "top",
    "product_images": [
      "https://cdn.yourstore.com/products/shirt-front.jpg"
    ],
    "product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg",
    "product_category": "t_shirt",
    "mannequin_id": "mnk_f3a9b1",
    "pose_id": "pose_c2d4e5",
    "background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg",
    "lock_background": true,
    "resolution": "2K",
    "aspect_ratio": "3:4",
    "body_size": "M",
    "expression": "neutral",
    "user_instruction": "Keep the collar pattern crisp and centered."
  }),
});
const { data } = await res.json(); // data.id, data.status
// Store { id: data.id, user_id, status: "processing" } in your jobs table
// and return { jobId: data.id } to the device.
// App polls YOUR /mobile/try-on/:id — you poll Photta server-side
// and mirror status. This way rate limits are YOUR problem, not
// each device's, and you can add caching + analytics in one place.
async function pollJob(jobId: string) {
  while (true) {
    const { status, imageUrl } = await api.get(`/mobile/try-on/${jobId}`);
    if (status === "completed") return imageUrl;
    if (status === "failed") throw new Error("Try-on failed");
    await sleep(3000);
  }
}

开发者常见问题

发布基于 Photta 的移动端功能

我可以从设备端直接调用 Photta API 吗?

技术上可行——但你必须将 API 密钥硬编码打包进应用安装包中,这意味着密钥会被分发到安装该应用的每一台设备上。请务必通过你自己的后端进行路由,将密钥保留在受控的服务器上。

如何应对不稳定的移动网络?

注意两点。第一:由后端提交任务,而不是设备端——手机只需将商品图片上传到你自己的 API。第二:以 3 秒间隔轮询你自己的状态 endpoint,并在失败时引入指数退避。如果用户切换应用或信号丢失,将 job ID 保存在本地存储中,以便用户返回时能够继续轮询。

Photta 支持 webhook 吗?

不支持。轮询是该 API 提供的唯一状态完成信号,因此请保留 worker 循环——并在你自己的后端捕获任务完成的瞬间,立即向手机端推送一条服务端发送事件(Server-Sent Events)。

我可以在 React Native 或 Flutter 中使用 Photta 吗?

可以——在 JavaScript / Dart 侧,你调用的只是你自己的后端 API。Photta 的底层实现细节完全不会穿透到客户端。Flutter 应用 fetch /mobile/try-on 的方式与 React Native 或原生 SwiftUI / Jetpack Compose 应用完全一致。

Apple 审核团队会在意这种集成方式吗?

不会——因为你的应用并未直接调用 Photta。它调用的是你自己的后端,使用你自己的鉴权体系。在 Apple 看来,这就是一个标准的 REST 架构应用。Google Play 和华为应用市场同理。

在下一个版本中上线虚拟试穿功能

三层轻量架构,设备端零 SDK 依赖。获取 API 密钥,一个下午即可完成代理对接。