客户没有登录,只是使用以前注册过的邮箱结账,页面却提示邮箱已存在并阻止下单。先不要直接删掉邮箱校验,这类拦截可能来自Magento核心配置,也可能是安全扩展为了防止账户枚举而加的Plugin。

先确定是谁返回了错误

浏览器开发者工具打开Network,重新输入邮箱,重点看 rest/*/V1/customers/isEmailAvailable 和提交shipping-information的响应。若接口返回 is_email_available:false 但页面只是给出登录提示,这是核心正常行为;若响应是异常或403,再查自定义模块。

bin/magento config:show checkout/options/guest_checkout
bin/magento config:show customer/account_share/scope
grep -R "isEmailAvailable|email already exists" app/code vendor/*/*/Plugin -n

两种场景要分开处理

  • 允许游客使用已注册邮箱下单:后台 Stores > Configuration > Sales > Checkout 中启用 Allow Guest Checkout。不要改CustomerRepository去绕过唯一邮箱约束,因为游客订单本来就不需要创建客户记录。
  • 业务要求必须登录:保留拦截,但把提示改成“该邮箱已有账户,请登录或使用验证码继续”,并把购物车ID保存在登录前,登录后执行guest cart与customer cart合并。
  • 多Website账户:确认 Share Customer Accounts 的范围。如果设为Per Website,测试时要用当前Website的客户记录,不能只查default website。

插件冲突怎么确认

临时只在测试环境执行 bin/magento module:disable Vendor_Module 并清理configuration与full_page缓存。若恢复,检查插件是否在 afterIsEmailAvailable 中无条件返回false。正确做法是读取当前websiteId,并仅在确实要求强制登录的Store范围拦截。

回归不要只测一个邮箱

  1. 全新邮箱以游客身份下单成功;
  2. 已有账户邮箱能按既定策略登录或游客下单;
  3. 登录前购物车在登录后仍保留;
  4. 两个Website分别测试同一邮箱;
  5. REST与GraphQL购物车流程各测一次。
不要通过直接更新 customer_entity.email 制造测试数据,容易留下地址、订单和索引关系不一致。使用后台或API创建专门的测试客户。