Bygg · Shopify
Bygg en try-on-app för Shopify
I en mening
En Shopify try-on-app läser produktbilden från Admin API, gör en POST till Photta, pollar jobbet i en bakgrundsworker och lämnar sedan över den färdiga URL:en till Shopify via productCreateMedia.
- Credits: 5 credits vid 2K · 6 credits vid 4K
- Typisk tid: 1.5–4 min
- Bearbetning: asynkron, polling
Varje siffra på den här sidan kommer från Photter API-dokumentationen · kontrollerad
Läs produktfotot från Admin API, rendera try-on med Photta och skicka tillbaka resultatet som produktmedia. Fyra anrop, ingen egen bildhantering.
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')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.statusimport os, requests
res = requests.post(
"https://api.photta.app/api/v1/tryon/apparel",
headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"},
json={
"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."
},
)
data = res.json()["data"] # data["id"], data["status"]Hur det fungerar
Från en produktsida till en try-on-bild
Begränsa appens scopes, läs fotot, skicka in, polla utanför anropskedjan, bifoga median.
Steg 1
Definiera appens scopes
En try-on-app behöver läsa produkter och skriva media. Be endast om de produkt-scopes din app faktiskt använder — handlare läser samtyckesskärmen.
Steg 2
Hämta en Photta API-nyckel
En nyckel per miljö, sparad i din apps konfiguration på serversidan. Den skickas aldrig till storefronten eller handlarens webbläsare.
Steg 3
Läs produktbilden
Fråga produkten efter dess första bild. Den URL:en är offentlig, vilket är precis vad Phottas endpoint förväntar sig — ingen återuppladdning, inga signerade URL:er att hantera.
Steg 4
Skicka in för try-on
Gör en POST med bilden tillsammans med en skyltdocka och en pose. Svaret kommer direkt och innehåller ett generation id; ingenting är renderat ännu.
Steg 5
Polla i ett bakgrundsjobb
Shopify förväntar sig att en webhook-hanterare svarar inom sekunder, och en generering tar längre tid än så. Bekräfta mottagandet, lägg i kö och polla var 3:e sekund från din worker.
Steg 6
Bifoga median
Ge Shopify den färdiga URL:en så laddar de ner filen själva. Spara även bilden på din sida, så att galleriet förblir intakt oberoende av Shopify.
De fyra anropen, från start till mål
Photta-begäran och pollingen återges från API-dokumentationen; Shopify-anropen är Admin API:s egna.
// 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.statusasync 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" }],
},
});Vanliga utvecklarfrågor
Frågor som Shopify-utvecklare ställer
Var ska Photta-nyckeln ligga i en Shopify-app?
I appserverns miljö, aldrig i temat, ett app block eller i ett app proxy-svar. Allt som storefronten kan läsa kan även en kund läsa.
Vilka Shopify-scopes krävs för detta?
Läsa produktbilden och skriva produktmedia. Photta behöver ingen åtkomst alls till Shopify — din app är det enda som pratar med båda sidor.
Hur håller jag min webhook snabb?
Bekräfta omedelbart, lägg jobbet i kö och polla från en worker. En generering tar längre tid än vad en webhook-hanterare bör ta, så inget som väntar på den hör hemma i hanteraren.
Kan jag debitera handlare per bild?
Det är ditt eget prissättningsbeslut. Photta debiterar ditt konto i credits per anrop, så kostnaden per bild är känd innan du renderar; vad du tar ut utöver det är upp till dig.
Vad händer om en produkt saknar foto?
Hoppa över den istället för att skicka en platshållare. Endpointen behöver ett riktigt fotografi av plagget, och en platshållare förbrukar credits på en bild som ingen kommer att publicera.
Relaterade sidor
Relaterad läsning
Funktioner
API för virtuell try-on för apparel
REST API som placerar kläder på AI-mannekänger. Asynkron, 1,5–4 minuters generering, 5 credits vid 2K, 6 vid 4K. Exempel för cURL, Node.js och Python.
LäsSnabbstart
Första Photta-bilden på under fem minuter.
Skapa konto, generera en API-nyckel, kör ditt första cURL-anrop, polla tills det är klart, spara resultatet. Fem steg, dokumenterade från början till slut.
LäsSpråk
Node.js walkthrough
LäsRate limits
Läs
Varje siffra på den här sidan kommer från Photter API-dokumentationen · kontrollerad
Leverera appen, inte infrastrukturen
Photta-anropen på den här sidan är hämtade direkt från API-dokumentationen. Hämta en nyckel så är den första renderingen bara minuter bort.