Byg · Shopify

Byg en Shopify-try-on-app

I én sætning

En Shopify-try-on-app læser produktbilledet fra Admin API, poster det med POST til Photta, poller jobbet i en background worker og overleverer derefter den færdige URL til Shopify via productCreateMedia.

  • Credits: 5 credits ved 2K · 6 credits ved 4K
  • Typisk tid: 1.5–4 min
  • Behandling: async, polling

Hvert tal på denne side stammer fra Photta API-dokumentationen · tjekket

Læs produktbilledet fra Admin API, render try-on med Photta, og send resultatet tilbage som produktmedie. Fire kald, ingen egen billedhåndtering.

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

Sådan virker det

Fra en produktside til et try-on-billede

Afgræns appens scopes, læs billedet, indsend, poll uden for request-stien, vedhæft mediet.

  1. Trin 1

    Afgræns appens scopes

    En try-on-app skal læse produkter og skrive medier. Bed kun om de produkt-scopes, din app rent faktisk bruger, og intet andet — forhandlere læser samtykkeskærmen.

  2. Trin 2

    Hent en Photta API-nøgle

    Én nøgle pr. miljø, gemt i din apps server-side-konfiguration. Den sendes aldrig til storefronten eller til forhandlerens browser.

  3. Trin 3

    Læs produktbilledet

    Forespørg produktet for dets første billede. Den URL er offentlig, hvilket er præcis, hvad Photta-endpointet forventer — ingen gen-upload, ingen signed URL at administrere.

  4. Trin 4

    Indsend try-on

    POST billedet med en mannequin og en positur. Svaret er øjeblikkeligt og indeholder generations-id'et; intet er renderet endnu.

  5. Trin 5

    Poll i et baggrundsjob

    Shopify forventer, at en webhook-handler svarer på få sekunder, og en generering tager længere tid end det. Kvittér, sæt i kø, og poll hvert 3. sekund fra workeren.

  6. Trin 6

    Vedhæft mediet

    Overlever den færdige URL til Shopify, hvorefter den selv downloader filen. Gem også billedet på din egen side, så galleriet overlever uafhængigt.

De fire kald, end-to-end

Photta-anmodningen og polling er gengivet fra API-dokumentationen; Shopify-kaldene er Admin API'ets egne.

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

Spørgsmål udviklere stiller

Spørgsmål, Shopify-udviklere stiller

Hvor placeres Photta-nøglen i en Shopify-app?

I din app-servers miljø, aldrig i temaet, en app-blok eller et app-proxy-svar. Alt, hvad storefronten kan læse, kan en kunde læse.

Hvilke Shopify-scopes kræver dette?

Læsning af produktbilledet og skrivning af produktmedier. Photta behøver overhovedet ingen Shopify-adgang — din app er det eneste, der taler med begge parter.

Hvordan holder jeg webhooken hurtig?

Kvittér med det samme, sæt arbejdet i kø, og poll fra workeren. En generering tager længere tid, end en webhook-handler bør tage, så intet, der venter på den, hører hjemme i handleren.

Kan jeg fakturere forhandlere pr. billede?

Det er din egen prissætningsbeslutning. Photta debiterer din konto i credits pr. kald, så prisen pr. billede er kendt, før du renderer; hvad du opkræver oveni, er op til dig.

Hvad hvis et produkt ikke har noget billede?

Spring det over frem for at sende et placeholder-billede. Endpointet kræver et reelt tøjfotografi, og en placeholder bruger credits på et billede, som ingen vil publicere.

Lever appen, ikke rørføringen

Photta-kaldene på denne side stammer direkte fra API-dokumentationen. Hent en nøgle, og den første rendering er blot minutter væk.