如何让Shopify结账验证Function仅在结账阶段运行,而非其他购物车操作
问题描述
我开发了一个Shopify Function作为购物车和结账验证扩展,用于强制用户填写姓名和电话字段。虽然Shopify后台有原生设置可以实现这个功能,但启用Shopify B2B的「配送至任意地址」选项会覆盖该设置。
目前遇到的问题是:这个Function会在非结账的购物车操作(比如添加商品到购物车)时运行,导致已登录但未关联姓名或电话的用户在加购时触发错误。我尝试在run.js中添加多种条件判断(如检查deliveryAddress、deliveryOptions等)来识别结账阶段,但这些字段在结账前也能被获取到,无法有效区分。
请问有没有办法让这个Function仅在结账时执行?
以下是我的配置和代码:
shopify.extension.toml
api_version = "2024-10" [[extensions]] name = "t:name" handle = "required-input-field-validations" type = "function" description = "t:description" [[extensions.targeting]] target = "purchase.validation.run" input_query = "src/run.graphql" export = "run" [extensions.build] command = "" path = "dist/function.wasm"
run.js
// @ts-check /** * @typedef {import("../generated/api").RunInput} RunInput * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult */ /** * The entry point for the Shopify Function * * @param {RunInput} input * @returns {FunctionRunResult} */ export function run(input) { const errors = []; // Access delivery address information from the input const deliveryGroups = input.cart.deliveryGroups || []; const deliveryAddress = deliveryGroups[0]?.deliveryAddress || {}; const firstName = deliveryAddress.firstName || ''; const lastName = deliveryAddress.lastName || ''; const phone = deliveryAddress.phone || ''; // Debugging logs console.log('First Name:', firstName); console.log('Last Name:', lastName); console.log('Phone:', phone); // Validate First Name if (!firstName.trim()) { errors.push({ localizedMessage: 'Please enter your first name.', target: 'deliveryAddressFirstName', }); } // Validate Last Name if (!lastName.trim()) { errors.push({ localizedMessage: 'Please enter your last name.', target: 'deliveryAddressLastName', }); } // Validate Phone Number if (!phone.trim()) { errors.push({ localizedMessage: 'Please enter your phone number.', target: 'deliveryAddressPhone', }); } return { errors }; }
解决方案
要让你的Purchase Validation Function仅在结账阶段执行,核心是通过Shopify提供的validationContext字段判断当前操作类型。在2024-10版本的API中,RunInput包含该字段,其中的action属性可标识当前操作是结账提交、结账更新还是购物车操作。
具体修改步骤如下:
1. 更新输入查询(run.graphql)
首先需要在src/run.graphql中添加validationContext字段,确保能获取操作类型:
query RunInputQuery { cart { deliveryGroups { deliveryAddress { firstName lastName phone } } # 添加以下字段 validationContext { action } } }
2. 修改run.js中的验证逻辑
在run函数开头添加条件判断,仅当操作类型为结账相关时才执行验证:
// @ts-check /** * @typedef {import("../generated/api").RunInput} RunInput * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult */ /** * The entry point for the Shopify Function * * @param {RunInput} input * @returns {FunctionRunResult} */ export function run(input) { const errors = []; // 仅在结账提交或结账更新阶段执行验证 const allowedActions = ["CHECKOUT_SUBMIT", "CHECKOUT_UPDATE"]; const currentAction = input.cart.validationContext?.action; if (!allowedActions.includes(currentAction)) { // 非结账操作直接返回空错误数组 return { errors }; } // Access delivery address information from the input const deliveryGroups = input.cart.deliveryGroups || []; const deliveryAddress = deliveryGroups[0]?.deliveryAddress || {}; const firstName = deliveryAddress.firstName || ''; const lastName = deliveryAddress.lastName || ''; const phone = deliveryAddress.phone || ''; // Debugging logs console.log('First Name:', firstName); console.log('Last Name:', lastName); console.log('Phone:', phone); // Validate First Name if (!firstName.trim()) { errors.push({ localizedMessage: 'Please enter your first name.', target: 'deliveryAddressFirstName', }); } // Validate Last Name if (!lastName.trim()) { errors.push({ localizedMessage: 'Please enter your last name.', target: 'deliveryAddressLastName', }); } // Validate Phone Number if (!phone.trim()) { errors.push({ localizedMessage: 'Please enter your phone number.', target: 'deliveryAddressPhone', }); } return { errors }; }
关键说明
validationContext.action的可选值:CHECKOUT_SUBMIT:用户提交结账时触发CHECKOUT_UPDATE:结账过程中更新信息(如修改地址)时触发CART_UPDATE:购物车操作(如添加/删除商品)时触发
- 通过判断
currentAction是否属于允许的结账操作类型,可跳过购物车阶段的验证,避免已登录用户加购时触发错误。
内容的提问来源于stack exchange,提问作者Alex Zelinsky
相关产品推荐
相关产品推荐

