Wdrożenie · Shopify

Zbuduj aplikację try-on dla Shopify

W jednym zdaniu

Aplikacja try-on dla Shopify odczytuje zdjęcie produktu z Admin API, wysyła je żądaniem POST do Photta, odpytuje o status zadania w tle (polling) i przekazuje gotowy URL do Shopify przez productCreateMedia.

  • Credits: 5 credits w 2K · 6 credits w 4K
  • Typowy czas: 1.5–4 min
  • Przetwarzanie: asynchroniczne, polling

Każda liczba na tej stronie pochodzi z dokumentacji API Photta · sprawdzono

Pobierz zdjęcie produktu z Admin API, wygeneruj try-on za pomocą Photta i prześlij wynik z powrotem jako media produktu. Cztery wywołania, zero przetwarzania obrazu po Twojej stronie.

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

Jak to działa

Od strony produktu do zdjęcia try-on

Zdefiniuj uprawnienia (scope), pobierz zdjęcie, wyślij żądanie, wykonaj polling poza głównym wątkiem, dołącz media.

  1. Krok 1

    Określ zakres uprawnień aplikacji

    Aplikacja try-on wymaga odczytu produktów i zapisu mediów. Poproś wyłącznie o te zakresy (scopes), których aplikacja rzeczywiście używa — sprzedawcy zwracają uwagę na ekran zgody.

  2. Krok 2

    Uzyskaj klucz API Photta

    Jeden klucz na środowisko, przechowywany w konfiguracji serwerowej aplikacji. Nigdy nie trafia do witryny sklepu ani do przeglądarki sprzedawcy.

  3. Krok 3

    Pobierz zdjęcie produktu

    Pobierz pierwsze zdjęcie z obiektu produktu. Ten adres URL jest publiczny, czyli dokładnie taki, jakiego wymaga endpoint Photta — bez ponownego przesyłania, bez zarządzania podpisanymi URL-ami.

  4. Krok 4

    Wyślij żądanie try-on

    Wyślij żądanie POST z obrazem, manekinem i pozą. Odpowiedź jest natychmiastowa i zawiera identyfikator generowania; renderowanie jeszcze się nie zakończyło.

  5. Krok 5

    Wykonaj polling w procesie w tle

    Shopify oczekuje odpowiedzi handlera webhooka w ciągu kilku sekund, a generowanie trwa dłużej. Zwróć potwierdzenie, dodaj zadanie do kolejki i odpytuj co 3 sekundy z poziomu workera.

  6. Krok 6

    Dołącz media

    Przekaż gotowy URL do Shopify, a platforma sama pobierze plik. Zachowaj kopię obrazu również po swojej stronie, aby galeria pozostała niezależna.

Cztery wywołania, end-to-end

Żądanie do Photta i polling bazują na dokumentacji API; wywołania Shopify to natywne operacje Admin API.

// Shopify Admin GraphQL — the product's first image is your source photo
const query = `query($id: ID!) {
  product(id: $id) { title images(first: 1) { nodes { url } } }
}`;

const res = await admin.graphql(query, { variables: { id: productGid } });
const { data } = await res.json();
const productImage = data.product.images.nodes[0].url;
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
async function waitFor(id) {
  for (let attempt = 0; attempt < 120; attempt++) {
    const res = await fetch(`https://api.photta.app/api/v1/tryon/apparel/${id}`, { headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}` } });
    const { data } = await res.json();
    if (data.status === "completed") return data.output_url;
    if (data.status === "failed") throw new Error(data.error_message ?? "generation failed");
    await new Promise((r) => setTimeout(r, 3000));
  }
  throw new Error("timed out after 6 minutes");
}
// Shopify downloads the URL itself, so hand it the Photta output_url
const mutation = `mutation($id: ID!, $media: [CreateMediaInput!]!) {
  productCreateMedia(productId: $id, media: $media) {
    mediaUserErrors { field message }
  }
}`;

await admin.graphql(mutation, {
  variables: {
    id: productGid,
    media: [{ originalSource: outputUrl, mediaContentType: "IMAGE", alt: "Virtual try-on" }],
  },
});

Pytania zadawane przez programistów

Pytania zadawane przez programistów Shopify

Gdzie przechowywać klucz Photta w aplikacji Shopify?

W zmiennych środowiskowych serwera aplikacji, nigdy w szablonie (theme), bloku aplikacji ani w odpowiedzi app proxy. Wszystko, co może odczytać storefront, może podejrzeć również klient.

Jakich uprawnień Shopify wymaga to wdrożenie?

Odczytu zdjęć produktów i zapisu mediów produktu. Photta nie potrzebuje żadnego bezpośredniego dostępu do Shopify — to Twoja aplikacja pośredniczy w komunikacji między obiema platformami.

Jak zapewnić szybką odpowiedź webhooka?

Zwróć potwierdzenie natychmiast, zakolejkuj pracę i wykonuj polling z poziomu workera. Generowanie trwa dłużej, niż powinien trwać cykl życia handlera webhooka — nic, co na nie czeka, nie powinno blokować handlera.

Czy mogę rozliczać sprzedawców za każde zdjęcie?

Model wyceny zależy wyłącznie od Ciebie. Photta obciąża Twoje konto w credits za każde wywołanie, więc koszt pojedynczego wygenerowania znasz z góry; narzut zależy od Ciebie.

Co w przypadku, gdy produkt nie ma zdjęcia?

Pomiń go, zamiast wysyłać placeholder. Endpoint wymaga rzeczywistego zdjęcia odzieży, a placeholder zużywa credits na obraz, którego nikt nie opublikuje.

Wdrażaj aplikację, nie infrastrukturę

Przedstawione wywołania Photta pochodzą wprost z dokumentacji API. Pobierz klucz, a pierwszy render uzyskasz w kilka minut.