구현 · WooCommerce

WooCommerce try-on 플러그인 만들기

한 줄 요약

WooCommerce 플러그인이 WP-Cron 이벤트에서 일반 HTTP로 Photta API를 호출하고, 다음 틱에서 작업을 폴링한 후, 완성된 이미지를 미디어 라이브러리로 가져옵니다.

  • 크레딧: 2K에서 5 크레딧 · 4K에서 6 크레딧
  • 일반적인 소요 시간: 1.5–4 min
  • 처리 방식: 비동기, 폴링

이 페이지의 모든 수치는 다음 출처를 기반으로 합니다: Photta API 문서 · 확인 완료

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 틱, 폴링, 그리고 미디어 가져오기

플러그인 기획, 작업 예약, 제출, 다음 틱에서 폴링, 가져오기 순으로 진행됩니다.

  1. 단계 1

    플러그인 기획하기

    대기열 테이블 하나, cron 훅 하나, 키를 입력할 설정 화면 하나면 충분합니다. 페이지 요청 중에는 생성이 절대 일어나지 않으므로 구매자의 작업이 지연될 염려가 없습니다.

  2. 단계 2

    Photta API 키 발급받기

    옵션 테이블에 저장하지 말고 wp-config.php의 환경 변수에서 읽어오도록 하세요. 그래야 데이터베이스를 내보낼 때 인증 자격 증명이 노출되지 않습니다.

  3. 단계 3

    cron 이벤트 예약하기

    반복 훅을 등록하고 실행당 대기 중인 제품을 적당량만 가져오세요. 실제 트래픽이 있는 사이트는 틱이 자주 발생하지만, 트래픽이 적은 사이트는 실제 시스템 cron이 필요합니다.

  4. 단계 4

    제품 제출하기

    cURL 샘플과 동일한 URL, 헤더, JSON 본문으로 wp_remote_post를 통해 제품 이미지를 전송하세요. 반환된 id는 대기열 행에 저장합니다.

  5. 단계 5

    다음 틱에서 폴링하기

    아직 processing 상태인 모든 행의 상태를 확인합니다. 틱 간격이 몇 분 정도이므로 틱당 한 번의 폴링으로 대체로 충분하며, 요청 내부에서 대기 상태(sleep)가 발생하지 않습니다.

  6. 단계 6

    이미지 가져오기

    작업이 완료되면 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는 Bearer 헤더를 사용하는 HTTPS 기반의 일반적인 REST 형식이므로, 업데이트를 관리해야 할 의존성 없이 wp_remote_post만으로 모든 것을 처리할 수 있습니다.

PHP에서는 어떻게 호출하나요?

Authorization 및 Content-Type 헤더와 JSON 본문을 포함하여 wp_remote_post를 사용합니다. 이 페이지의 cURL 샘플과 필드 하나하나까지 정확히 같은 요청입니다.

왜 페이지 로드 시점에 생성하지 않나요?

생성 작업은 단일 페이지 요청보다 오래 걸립니다. 요청 도중에 렌더링을 진행하면 구매자가 대기하게 되고, 타임아웃으로 요청이 중단되더라도 credits는 그대로 차감됩니다.

한 번 실행할 때 몇 개의 제품을 처리해야 하나요?

틱당 적은 양을 처리하여 여러 틱에 걸쳐 대기열이 비워지도록 하세요. 이렇게 하면 각 실행 시간을 짧게 유지할 수 있고 공식 rate limit도 안전하게 준수할 수 있습니다.

실패한 작업은 어떻게 처리되나요?

해당 행을 failed로 표시하고 응답에서 오류 유형을 보관하세요. 실패한 생성에 사용된 credits는 자동으로 환불되므로 재시도해도 비용이 이중으로 청구되지 않습니다.

의존성 트리가 없는 플러그인

Bearer 헤더, JSON 본문, 폴링. 모두 WordPress에서 이미 기본으로 제공하는 기능입니다.