Разработка · WooCommerce

Создание плагина виртуальной примерки (try-on) для WooCommerce

В двух словах

Плагин для WooCommerce вызывает API Photta по обычному HTTP из события WP-Cron, опрашивает задачу на следующем тике и импортирует готовое изображение в медиабиблиотеку.

  • Кредиты: 5 credits при 2K · 6 credits при 4K
  • Типичное время: 1.5–4 min
  • Обработка: async, polling

Все показатели на этой странице взяты из документации API Photta · проверено

PHP SDK не требуется. WP-Cron отправляет задачу, следующий тик опрашивает статус, а 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')

Как это работает

Тик cron, polling и импорт в медиабиблиотеку

Спланируйте плагин, настройте расписание, отправьте задачу, опросите на следующем тике, импортируйте.

  1. Шаг 1

    Спланируйте плагин

    Одна таблица очереди, один cron-хук, один экран настроек для ключа. Генерация никогда не происходит во время запроса страницы, поэтому действия покупателя не могут зависнуть.

  2. Шаг 2

    Получите API-ключ Photta

    Считывайте его из переменных окружения в wp-config.php, а не храните в таблице options, чтобы экспорт базы данных не содержал ваши учетные данные.

  3. Шаг 3

    Настройте cron-событие

    Зарегистрируйте повторяющийся хук и обрабатывайте небольшую пачку товаров из очереди за один запуск. Сайт с реальным трафиком получает частые тики; сайту без трафика потребуется настоящий системный cron.

  4. Шаг 4

    Отправьте товар

    Отправьте изображение товара через wp_remote_post — те же URL, заголовки и JSON-тело, что и в примере с cURL. Сохраните полученный id в строке очереди.

  5. Шаг 5

    Опросите статус на следующем тике

    Считайте статус для каждой строки со статусом processing. Поскольку между тиками проходят минуты, одного polling-запроса за тик обычно достаточно; внутри веб-запроса ничего не уходит в sleep.

  6. Шаг 6

    Импортируйте изображение

    Как только задача завершена (completed), импортируйте URL в медиабиблиотеку и прикрепите к товару. Скачивание выполняет WP-CLI, поэтому плагин не буферизует файл в памяти.

Четыре составляющие плагина

Вызовы к Photta соответствуют документации API; wp_remote_post принимает те же URL, заголовки и тело запроса.

# 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 представляет собой обычный REST по HTTPS с заголовком Bearer, поэтому wp_remote_post покрывает все задачи без необходимости обновлять внешние зависимости.

Как сделать вызов из PHP?

Используйте wp_remote_post с заголовками Authorization и Content-Type, а также телом запроса в формате JSON. Пример cURL на этой странице — это ровно тот же запрос, поле в поле.

Почему бы не генерировать прямо при загрузке страницы?

Генерация длится дольше, чем допустимое время ответа страницы. Рендеринг внутри веб-запроса заставляет покупателя ждать, обрывается по таймауту, а credits в любом случае списываются.

Сколько товаров брать за один запуск?

Берите небольшую порцию на каждый тик и опустошайте очередь постепенно между тиками. Это сохраняет запуски короткими и удерживает вас в рамках установленного rate limit.

Что происходит с упавшими задачами?

Пометьте строку как failed и сохраните тип ошибки из ответа. Credits за неудачную генерацию возвращаются автоматически, поэтому повторная попытка не оплачивается дважды.

Плагин без дерева зависимостей

Заголовок Bearer, JSON-тело, polling. Всё то, что WordPress уже умеет из коробки.