Xây dựng · Try-On cho thiết bị di động

Thêm virtual try-on vào ứng dụng iOS hoặc Android

Tóm tắt trong một câu

Lưu trữ Photta API key trên backend của bạn; mở một endpoint proxy (/mobile/try-on) nhận ảnh sản phẩm cùng mannequin ID, chuyển tiếp tới /api/v1/tryon/apparel, lưu generation ID theo user tương ứng, và mở một endpoint trạng thái để ứng dụng di động polling mỗi 3 giây một lần cho đến khi ảnh xử lý xong. Thiết bị hoàn toàn không biết sự tồn tại của Photta key.

  • Credits: 5 credits ở 2K · 6 credits ở 4K
  • Thời gian điển hình: 1.5–4 min
  • Xử lý: async, polling

Mọi số liệu trên trang này đều lấy từ tài liệu Photta API · đã kiểm tra

Thiết bị của bạn không bao giờ giao tiếp trực tiếp với Photta — nó gọi tới backend của bạn, và backend sẽ gọi tới Photta. Ranh giới đó giúp giữ API key không bị lộ trên điện thoại người dùng, biến rate limit thành bài toán nội bộ do bạn kiểm soát, và đảm bảo ứng dụng vượt qua khâu kiểm duyệt trên mọi kho ứng dụng.

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')

Cơ chế hoạt động

Thiết bị, backend, Photta — ba tầng, một luồng xử lý

Năm quyết định cụ thể bạn cần đưa ra trước lần gửi duyệt App Store đầu tiên.

  1. Bước 1

    Giữ API key an toàn trên server của bạn

    Không đóng gói Photta key vào binary của app, info.plist, AndroidManifest hoặc bất kỳ file env nào trong quá trình build — việc dịch ngược binary rất dễ dàng và key chắc chắn sẽ bị lộ. Backend là nơi duy nhất key được phép tồn tại.

  2. Bước 2

    Thiết kế một endpoint proxy tinh gọn

    Mở endpoint /mobile/try-on cho ứng dụng của bạn. Xác thực request bằng user session của chính bạn — không chuyển tiếp trực tiếp API key thô qua proxy. Proxy sau đó sẽ thay mặt người dùng đã xác thực để gọi Photta.

  3. Bước 3

    Đồng bộ trạng thái job của Photta trong cơ sở dữ liệu của bạn

    Khi Photta trả về một generation ID, hãy chèn một bản ghi vào bảng jobs của bạn với khóa là user_id. Ứng dụng di động sẽ thực hiện polling tới /mobile/try-on/:id CỦA BẠN — không phải của Photta — nhờ đó rate limit sẽ co giãn theo gói cước CỦA BẠN chứ không phụ thuộc vào thiết bị của từng người dùng.

  4. Bước 4

    Cache URL kết quả

    Khi Photta báo completed, hãy sao chép output_url vào bản ghi jobs của bạn và có thể tùy chọn tải dữ liệu byte về CDN riêng. Người dùng di động phải trả phí theo từng MB — đừng hot-link trực tiếp CDN của Photta cho toàn bộ vòng đời hiển thị của một trang PDP.

  5. Bước 5

    Xử lý trạng thái offline một cách mềm dẻo

    Kết nối mạng di động có thể rớt giữa chừng khi đang polling. Hãy hiển thị trạng thái 'đang thử lại' thay vì báo lỗi nghiêm trọng, thực hiện retry với exponential backoff, và lưu job ID vào bộ nhớ cục bộ để khi cold-start ứng dụng có thể tiếp tục đúng điểm mà phiên trước bị gián đoạn.

Ba tầng của kiến trúc tích hợp

Hợp đồng ứng dụng, backend proxy, client-side polling — chính xác là ranh giới kiến trúc bạn cần.

// 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);
  }
}

Câu hỏi thường gặp từ developer

Triển khai tính năng trên ứng dụng di động dùng Photta

Tôi có thể gọi Photta API trực tiếp từ thiết bị không?

Về mặt kỹ thuật là có — nhưng bạn sẽ phải đóng gói API key bên trong app bundle, điều này đồng nghĩa với việc phát tán key tới mọi thiết bị cài đặt ứng dụng. Hãy định tuyến qua backend của chính bạn để key luôn nằm trên server do bạn kiểm soát.

Tôi nên xử lý kết nối mạng di động chậm như thế nào?

Hai điểm cần lưu ý. Một: gửi job từ backend, không phải từ thiết bị — điện thoại chỉ cần tải ảnh sản phẩm lên API của bạn. Hai: polling endpoint trạng thái của chính bạn theo chu kỳ 3 giây kèm exponential backoff khi thất bại. Nếu người dùng chuyển tab hoặc mất sóng, hãy lưu job ID vào local storage để họ có thể tiếp tục khi quay lại.

Photta có hỗ trợ webhook không?

Không. Polling là tín hiệu hoàn thành duy nhất mà API cung cấp, vì vậy hãy duy trì worker loop — và push một server-sent event tới điện thoại ngay thời điểm backend của bạn phát hiện job đã hoàn tất.

Tôi có thể dùng Photta với React Native hoặc Flutter không?

Có — từ phía JavaScript / Dart, bạn chỉ đang gọi API backend của chính mình. Toàn bộ logic nội bộ của Photta không hề bị rò rỉ ra ngoài. Các ứng dụng Flutter gọi fetch /mobile/try-on tương tự như cách một ứng dụng React Native hay native SwiftUI / Jetpack Compose thực hiện.

Đội ngũ kiểm duyệt của Apple có bận tâm về việc tích hợp này không?

Không — vì ứng dụng của bạn không trực tiếp gọi Photta. Nó đang gọi backend của bạn với hệ thống xác thực riêng của bạn. Dưới góc nhìn của Apple, đây chỉ là một ứng dụng REST thông thường. Điều tương tự cũng áp dụng cho Google Play và Huawei AppGallery.

Triển khai virtual try-on trong bản phát hành ứng dụng tiếp theo của bạn

Ba tầng kiến trúc mỏng, hoàn toàn không tốn dung lượng SDK trên thiết bị. Lấy một API key và hoàn thiện proxy chỉ trong một buổi chiều.