VTO API Serviceは、HMAC署名とJWTトークンを組み合わせた2段階の認証フローを採用しています。 まずサーバー側でHMAC署名を生成し、トークンエンドポイントからJWTを取得。その後、JWTを用いてWidgetを認証し、 VTOやステータス取得を行います。
// 署名対象文字列: api_key|origin|timestamp(パイプ区切り)
message = "api_XXXX-XXXX-XXXX-XXXX|https://your-ec-site.com|1710345600"
signature = hmac_sha256(message, shared_secret)
// PHP例:
$message = $apiKey . '|' . $origin . '|' . $timestamp;
$signature = hash_hmac('sha256', $message, $sharedSecret);
パラメータ:
api_key: マイページで取得したAPIキー(api_XXXX-XXXX-XXXX-XXXX)origin: ECサイトのオリジン(例: https://your-ec-site.com)timestamp: 現在のUnixタイムスタンプ(秒)※ ±5分以内shared_secret: マイページで確認できるシークレットキーPOST /API/api/token.php
Content-Type: application/json
{
"api_key": "api_XXXX-XXXX-XXXX-XXXX",
"origin": "https://your-ec-site.com",
"timestamp": 1710345600,
"signature": "hmac_sha256_hex_string"
}
レスポンス:
{
"success": true,
"data": {
"widget_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 3600
}
}
取得した widget_token は Widget JS が自動で使用します。
お客様サーバーにプロキシPHPを設置し、Widget JS の tokenEndpoint に指定してください。
<script src="https://asp.kitemir.jp/API_SERVICES/widget/vto-widget.js"></script>
<link rel="stylesheet" href="https://asp.kitemir.jp/API_SERVICES/widget/vto-widget.css">
<script>
VtoWidget.init({
tokenEndpoint: '/api/widget_token.php', // お客様サーバーのプロキシPHP
apiBase: 'https://asp.kitemir.jp/API_SERVICES'
});
</script>
<!-- 商品ページに試着ボタンを設置 -->
<button onclick="VtoWidget.open({
garmentUrl: 'https://your-ec-site.com/images/product.webp',
category: 'tops',
productName: 'エレガントブラウス',
productPrice: 12000,
onAddToCart: function() { addToMyCart(123); }
})">試着してみる</button>
概要: HMAC署名からJWTトークンを取得します
認証: HMAC署名
レート制限: 1IP/分あたり30リクエスト
概要: バーチャル試着を実行します(非同期)
認証: Bearer JWT(widget_token)
Content-Type: multipart/form-data または application/json
パラメータ:
person_image (file/base64): ユーザーの身体写真(JPEG/PNG)garment_url (string): 試着用服画像のURL(https://〜)category (string): tops / bottoms / one-pieces / auto注意: garment_url はURLを指定します(ファイルアップロードではありません)。サーバー側で画像をダウンロードして FASHN AI に送信します。
概要: VTO実行のステータスを確認(ポーリング用)
認証: Bearer JWT
推奨ポーリング間隔: 2〜3秒
ステータス値:
queued: キュー待機中processing: 処理中completed: 完了(result_url / designer_comment 付き)failed: 失敗(error_message 付き)概要: ライセンスキーの有効性確認(初期設定用・CORS対応)
認証: 不要(ライセンスキーのみ検証)
用途: 初期セットアップ画面でのキー検証
リクエスト:
curl -X POST https://asp.kitemir.jp/API/api/token.php \
-H "Content-Type: application/json" \
-d '{
"api_key": "api_1234-5678-9abc-def0",
"origin": "https://your-ec-site.com",
"timestamp": 1710345600,
"signature": "a1b2c3d4e5f6..."
}'
レスポンス(成功):
{
"success": true,
"data": {
"widget_token": "eyJhbGciOiJIUzI1NiIs...",
"expires_in": 3600
}
}
multipart/form-data 方式:
curl -X POST https://asp.kitemir.jp/API/api/tryon.php \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-F "person_image=@person.jpg" \
-F "garment_url=https://your-ec-site.com/images/dress.webp" \
-F "category=one-pieces"
JSON方式(base64):
curl -X POST https://asp.kitemir.jp/API/api/tryon.php \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"person_image": "/9j/4AAQSkZJRg...(base64)",
"garment_url": "https://your-ec-site.com/images/dress.webp",
"category": "one-pieces"
}'
レスポンス(成功):
{
"success": true,
"data": {
"tryon_id": "pred_abc123def456",
"status": "processing"
}
}
リクエスト:
curl -X GET "https://asp.kitemir.jp/API/api/status.php?tryon_id=vto_1710345678_abc123" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
レスポンス(完了):
{
"success": true,
"data": {
"status": "completed",
"result_url": "https://cdn.fashn.ai/results/tryon_123456.jpg",
"designer_comment": "このワンピースはあなたの優雅さを引き出しており、非常に素敵です。深い色合いは肌のトーンを美しく見せ、シルエットは体を的確にサポートしています。特に首周りのデザインは顔立ちを柔らかく見せています。",
"cost_usd": 0.075
}
}
VTO Widgetでは、試着結果画面に「カートに追加する」ボタンが表示されます。
このボタンがクリックされたときに実行される処理を onAddToCart コールバック関数で自由に定義できます。
お客様のECサイトのカートシステムに合わせて、AJAX送信やフォーム操作などを記述してください。
onAddToCart は2つの場所で設定できます。
商品ページごとに異なるカート処理を定義できます。
<button onclick="VtoWidget.open({
garmentUrl: 'https://your-site.com/images/blouse.webp',
category: 'tops',
productName: 'エレガントブラウス',
productPrice: 12000,
onAddToCart: function() {
// ここに自社カートへの追加処理を記述
addToMyCart(商品ID, サイズ, カラー);
}
})">試着してみる</button>
全商品共通のカート処理を初期化時に設定します。open() で個別指定した場合はそちらが優先されます。
VtoWidget.init({
tokenEndpoint: '/api/widget_token.php',
apiBase: 'https://asp.kitemir.jp/API_SERVICES',
onAddToCart: function() {
// グローバルのカート追加処理
alert('カートに追加しました');
}
});
onAddToCart: function() {
fetch('/api/cart', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
product_id: 123,
quantity: 1,
size: 'M',
color: 'ベージュ'
})
})
.then(res => res.json())
.then(data => {
if (data.success) {
// カートアイコンの数量を更新
document.getElementById('cart-count').textContent = data.cart_count;
alert('カートに追加しました');
}
});
}
onAddToCart: function() {
var form = document.getElementById('cart-form');
form.submit();
}
<?php foreach ($products as $product): ?>
<button onclick="VtoWidget.open({
garmentUrl: '<?= $product['tryon_image_url'] ?>',
category: '<?= $product['tryon_category'] ?>',
productName: '<?= htmlspecialchars($product['name']) ?>',
productPrice: <?= $product['price'] ?>,
onAddToCart: function() {
addToCart(<?= $product['id'] ?>);
}
})">試着してみる</button>
<?php endforeach; ?>
ポイント:
onAddToCart が実行された後、Widget は自動的に閉じます。
カート追加処理が非同期(AJAX)の場合でも、Widgetは即座に閉じるため、処理完了の通知はお客様のUI側で行ってください。
garmentUrls を使用して複数色を登録している場合、
onAddToCart コールバックの第1引数に、
ユーザーが選択中の色名(color フィールドの値)が自動で渡されます。
VtoWidget.open({
garmentUrls: [
{ url: '/tryon/dress-ivory.webp', color: 'アイボリー' },
{ url: '/tryon/dress-black.webp', color: 'ブラック' }
],
category: 'one-pieces',
productName: 'ワンピース',
productPrice: 8800,
onAddToCart: function(selectedColor) {
// selectedColor = 'ブラック'(ユーザーが選んだ色)
fetch('/api/cart', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
product_id: 456,
color: selectedColor, // ← Widgetから受け取った色名
quantity: 1
})
});
}
});
単色(garmentUrl のみ)の場合、第1引数は null になります。
同じ商品の色違い(最大7色)をWidget内で切り替えて試着できます。
garmentUrls 配列パラメータを使用すると、
試着服エリアに左右の矢印が表示され、ユーザーが色を選んでから試着を実行できます。
従来の garmentUrl(単一URL)も引き続きサポートしています。
garmentUrls が指定されていない場合は、矢印は表示されず従来通りの動作になります。
<button onclick="VtoWidget.open({
garmentUrls: [
{ url: 'https://your-site.com/tryon/blouse-beige.webp', color: 'ベージュ' },
{ url: 'https://your-site.com/tryon/blouse-navy.webp', color: 'ネイビー' },
{ url: 'https://your-site.com/tryon/blouse-black.webp', color: 'ブラック' },
{ url: 'https://your-site.com/tryon/blouse-wine.webp', color: 'ワインレッド' }
],
category: 'tops',
productName: 'クルーネックセーター',
productPrice: 12000,
onAddToCart: function() { addToCart(); }
})">試着してみる</button>
garmentUrls (Array) — 最大7件
url (String, 必須): 試着画像の絶対URL(https://〜)color (String, 任意): 色名(「ベージュ」等)Widget内に表示label (String, 任意): 表示ラベル(colorの代替)動作仕様
<?php
// 商品の色ごとに試着画像URLを配列化
$garmentUrls = [];
foreach ($product['colors'] as $color) {
$garmentUrls[] = [
'url' => 'https://your-site.com/tryon/' . $product['sku'] . '-' . $color['slug'] . '.webp',
'color' => $color['name'],
];
}
?>
<button onclick="VtoWidget.open({
garmentUrls: <?= json_encode($garmentUrls, JSON_UNESCAPED_UNICODE) ?>,
category: '<?= $product['vto_category'] ?>',
productName: '<?= htmlspecialchars($product['name']) ?>',
productPrice: <?= $product['price'] ?>,
onAddToCart: function() { addToCart(<?= $product['id'] ?>); }
})">試着してみる</button>
画像の推奨仕様: 白背景・正面平置きのJPEGまたはWebP形式。推奨サイズ 1024×1024px以下。 モデル着用写真も使用可能ですが、白背景の平置き画像の方がVTO精度が高くなります。
後方互換性:
従来の garmentUrl(単一URL文字列)は引き続きサポートされます。
garmentUrls が指定されていない場合は、矢印は表示されず従来通りの動作です。
既存の実装を変更する必要はありません。
| コード | エラー名 | 説明 |
|---|---|---|
| 400 | Bad Request | リクエストパラメータが不正です |
| 401 | Unauthorized | 認証に失敗しました(署名・トークン無効) |
| 403 | Forbidden | ライセンスが無効またはプランが非アクティブ |
| 402 | Payment Required | 月間VTO上限に達しました(プランのアップグレードが必要) |
| 500 | Internal Server Error | サーバーエラー(お問い合わせください) |
| 503 | Service Unavailable | VTOサービスが一時的に利用不可 |
💡 ヒント: すべてのエラーレスポンスは JSON形式で {"success": false, "error": "...", "code": 400} の形式で返されます。