构建 · WooCommerce
构建 WooCommerce 虚拟试衣插件
一句话总结
WooCommerce 插件通过 WP-Cron 事件在普通 HTTP 上调用 Photta API,在接下来的周期对任务进行 polling,并将生成的图片导入媒体库。
- Credits: 2K 分辨率 5 credits · 4K 分辨率 6 credits
- 常规耗时: 1.5–4 min
- 处理方式: 异步,轮询
本页所有数据均来自 Photta API 文档 · 已验证
无需 PHP SDK。WP-Cron 提交任务,下一个周期进行 polling,WP-CLI 将生成的图片导入媒体库。
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"]工作原理
一个 cron 周期、一次 poll 与一次媒体导入
规划插件架构、调度任务、提交请求、在下个周期 polling、导入图片。
步骤 1
规划插件架构
一个队列数据表、一个 cron hook、一个配置 Key 的设置页面。生成过程绝不会发生在页面请求期间,因此消费者的任何操作都不会被卡住。
步骤 2
获取 Photta API Key
在 wp-config.php 中从环境变量读取它,而不是存放在 options 表中,这样导出数据库时就不会泄漏你的凭证。
步骤 3
调度 cron 事件
注册一个定时 hook,每次运行处理队列中的少量商品。有真实流量的站点会频繁触发周期;流量较少的站点则需要配置真实的系统 cron。
步骤 4
提交商品
使用 wp_remote_post 发送商品图片——URL、headers 和 JSON body 与 cURL 示例完全一致。将返回的 id 保存在队列对应行中。
步骤 5
在下个周期进行 polling
读取所有仍处于 processing 状态的行。由于执行周期之间间隔数分钟,每个周期 poll 一次通常就已足够;请求内部无需进行任何 sleep 操作。
步骤 6
导入图片
任务状态变为 complete 后,将图片 URL 导入媒体库并关联到对应商品。WP-CLI 会负责下载操作,插件本身无需在内存中缓冲整个文件。
插件的四个核心组成部分
Photta 调用完全基于 API 文档实现;wp_remote_post 接收相同的 URL、headers 和 body。
# wp-config.php holds the key; the plugin reads it with getenv()
# define( 'PHOTTA_API_KEY', getenv( 'PHOTTA_API_KEY' ) );
export PHOTTA_API_KEY="photta_live_xxx"
export PHOTTA_BASE_URL="https://api.photta.app/api/v1"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')# $ID is data.id from the POST response. Poll every 3 seconds until status is "completed" or "failed".
for i in $(seq 1 120); do
RESULT=$(curl -s "https://api.photta.app/api/v1/tryon/apparel/$ID" -H "Authorization: Bearer $PHOTTA_API_KEY")
STATUS=$(echo "$RESULT" | jq -r '.data.status')
[ "$STATUS" = "completed" ] && break
[ "$STATUS" = "failed" ] && echo "generation failed" && exit 1
sleep 3
done
echo "$RESULT" | jq -r '.data.output_url'# WP-CLI does the download, so the plugin never buffers the file itself
wp media import "$OUTPUT_URL" \
--post_id="$PRODUCT_ID" \
--title="Virtual try-on" \
--featured_image开发者常见问题
WordPress 开发者常见问题
有官方 PHP SDK 吗?
没有。该 API 是基于 HTTPS 的标准 REST API,带有 bearer header,因此仅凭 wp_remote_post 即可完成所有操作,无需额外维护第三方依赖包。
如何在 PHP 中发起调用?
使用 wp_remote_post,并附带 Authorization 和 Content-Type headers 以及 JSON body。本页中的 cURL 示例与该请求完全对应,字段完全一致。
为什么不在页面加载时生成?
生成所需的时间远远超过了页面应有的加载时间。在请求期间进行渲染会让消费者陷入等待,请求可能会被超时中断,而无论成功与否 credits 都会被扣除。
单次运行应处理多少个商品?
每个周期处理一小部分,让队列跨周期逐步清空。这样可以确保单次运行足够简短,并让你严格处于官方公布的 rate limit 范围之内。
任务失败时会怎样?
将该行标记为 failed,并保留响应中的错误类型。生成失败的 credits 会自动退还,因此重试并不会产生重复扣费。