如何修复Shopify Rest API商品上传的变体重复错误?
问题
通过Shopify Rest API上传商品时触发错误,错误信息:
{ errors: { base: [ "The variant 'EU 40' already exists." ] } }
商品数据来自MongoDB,结构如下:
{ _id: new ObjectId("64db3748a42f997c0544eda0"), id: 'LORENZO-CAM_COBALTO', shopifyId: 'none', site: 'Brands Distribution', whichStore: 'uk', title: 'Duca di Morrone LORENZO CAM COBALTO', body_html: '<p>Made in: Italy<br/>Collection: Spring/Summer<br/>Gender: Man<br/>Type: Loafers<br/>Upper: suede<br/>Internal lining: leather<br/>Sole: rubber<br/>Details: round toe</p>', vendor: 'Duca di Morrone', product_type: 'Shoes', variants: [ { option1: 'EU 40', option2: 'Blue', title: 'Bodies', price: 29, inventory_management: 'shopify', inventory_quantity: 9 }, { option1: 'EU 41', option2: 'Blue', title: 'Bodies', price: 29, inventory_management: 'shopify', inventory_quantity: 18 }, // 其余变体省略 { option1: 'EU 40', option2: 'Brown', title: 'Bodies', price: 29, inventory_management: 'shopify', inventory_quantity: 12 } ], images: [ { src: 'https://www.brandsdistribution.com/prod/product-133457-1511628552.jpg/large.jpg' }, // 其余图片省略 ], __v: 3 }
请求代码:
let response = await modules.axios.post(`https://${datas.config[findProduct.whichStore].shop}.myshopify.com/admin/api/2023-07/products.json`, { product: { ...findProduct._doc, variants: variantsArr } }, { headers: { 'X-Shopify-Access-Token': datas.config[findProduct.whichStore].api } }) findProduct.shopifyId = response.data.product.id findProduct.save() functions.log(`${response.data.product.id} is added!`, 0, datas.config[findProduct.whichStore].shop) return response.data
目标是同步每个变体的颜色、尺码和库存到Shopify,需修复错误并调整数据格式。
解决方案
1. 添加产品选项定义(核心修复)
Shopify需要明确产品的选项维度(如尺码、颜色),否则会默认仅以option1作为变体唯一性判断依据,导致同尺码不同颜色的变体被识别为重复。在请求的product对象中添加options字段:
product: { ...findProduct._doc, options: [ { name: "Size" }, // 对应变体的option1 { name: "Color" } // 对应变体的option2 ], variants: variantsArr }
2. 修正变体的title字段
Shopify变体的title应是选项组合的描述(而非统一的"Bodies"),比如"EU 40 / Blue",帮助平台正确识别变体唯一性,同时符合规范。生成variantsArr时动态生成title:
const variantsArr = findProduct.variants.map(v => ({ ...v, title: `${v.option1} / ${v.option2}` }));
3. 区分创建与更新逻辑
如果shopifyId不为'none',说明商品已存在于Shopify,此时用PUT请求更新而非POST创建,避免重复冲突:
let response; const shopifyUrl = `https://${datas.config[findProduct.whichStore].shop}.myshopify.com/admin/api/2023-07/products`; if (findProduct.shopifyId !== 'none') { // 更新已有商品 response = await modules.axios.put(`${shopifyUrl}/${findProduct.shopifyId}.json`, { product: { ...findProduct._doc, options: [ { name: "Size" }, { name: "Color" } ], variants: variantsArr } }, { headers: { 'X-Shopify-Access-Token': datas.config[findProduct.whichStore].api } }); } else { // 创建新商品 response = await modules.axios.post(`${shopifyUrl}.json`, { product: { ...findProduct._doc, options: [ { name: "Size" }, { name: "Color" } ], variants: variantsArr } }, { headers: { 'X-Shopify-Access-Token': datas.config[findProduct.whichStore].api } }); findProduct.shopifyId = response.data.product.id; await findProduct.save(); }
4. 额外注意事项
- 确保变体的
option1和option2值格式统一,比如避免EU 40与EU40、eu 40混用; - 若启用库存管理,确保
inventory_quantity为合法数值,inventory_management保持shopify配置。
内容的提问来源于stack exchange,提问作者imkyssa
相关产品推荐
相关产品推荐

