跳转到主要内容

地址自动补全提供者实现

概述

WooCommerce 地址自动补全系统允许第三方服务在客户在结账过程中输入账单和收货地址时,提供地址建议。本指南解释了如何创建和注册自定义地址提供者,以与任何地址验证服务集成。

请注意,此实现将为短代码和基于块的结账注册提供者。

架构

地址自动补全系统由三个主要组件组成:

  1. 服务器端提供者 (PHP) - 处理提供者注册和配置
  2. 客户端提供者 (JavaScript) - 实现搜索和选择逻辑
  3. UI 组件 - 显示建议并处理用户交互(由 WooCommerce 实现,插件无需提供此功能)

注册服务器端提供者

第一步:创建 WC_Address_Provider 子类

创建一个 PHP 类,该类继承自 WC_Address_Provider:

<?php
/**
 * 自定义地址提供者实现
 *
 * @package YourPlugin
 */

namespace YourPlugin\Providers;

use WC_Address_Provider;

/**
 * 自定义地址提供者
 */
class Custom_Address_Provider extends WC_Address_Provider {
    
    /**
     * 提供者唯一标识符。
     *
     * @var string
     */
    public $id = 'custom-provider';
    
    /**
     * 提供者显示名称。
     *
     * @var string
     */
    public $name = '自定义地址提供者';
    
    /**
     * 可选的品牌 HTML,用于在建议中显示。
     *
     * @var string
     */
    public $branding_html = '<div class="custom-branding">提供者:自定义提供者</div>';
    
    /**
     * 构造函数
     */
    public function __construct() {
        // 初始化任何 API 客户端或配置。
    }
}

第二步:注册提供者

使用 woocommerce_address_providers 过滤器,将您的提供者注册到 WooCommerce:

/**
 * 注册自定义地址提供者
 *
 * @param array $providers 现有的提供者。
 * @return array 修改后的提供者列表。
 */
function register_custom_address_provider( $providers ) {
    // 仅在提供者类存在时注册
    if ( class_exists( 'YourPlugin\Providers\Custom_Address_Provider' ) ) {
        $providers[] = new \YourPlugin\Providers\Custom_Address_Provider();
    }
    
    return $providers;
}
add_filter( 'woocommerce_address_providers', 'register_custom_address_provider', 10, 1 );

注册客户端提供者

第三步:实现 JavaScript 函数

创建一个 JavaScript 文件,该文件实现客户端提供者的逻辑。

提供者对象 API

参数

  • _id string - 必须与服务器端提供商 ID 匹配的唯一标识符。
  • _canSearch function - 用于确定提供商是否支持在给定国家/地区进行搜索的函数。
    • 参数:
      • _country string - 两位字母的国家/地区代码(例如,'US'、'GB')。
    • 返回值:boolean - 指示提供商是否支持该国家/地区。
  • _search function - 异步函数,用于搜索地址建议。
    • 参数:
      • _query string - 用户输入的文本(最小 3 个字符)。
      • _country string - 所选国家/地区的两位字母国家/地区代码。
      • _type string - 地址类型,可以是 'billing' 或 'shipping'。
    • 返回值:Promise<Array> - 解决为包含建议对象的数组的 Promise。
  • _select function - 异步函数,用于检索完整的地址详情。
    • 参数:
      • _addressId string - 所选建议的 ID。
    • 返回值:Promise<Object|null> - 解决为地址对象或在发生错误时返回 null 的 Promise。

建议对象格式

search 函数必须返回具有以下结构的建议对象:

  • _id string - 此建议的唯一标识符。
  • _label string - 显示给用户的文本。
  • _matchedSubstrings array (可选) - 用于突出显示标签中文本范围的文本范围数组。
    • _offset number - 匹配文本的起始位置。
    • _length number - 匹配文本的长度。

地址对象格式

select 函数必须返回具有以下 WooCommerce 字段名称的地址对象:

  • _address_1 string - 主要地址行。
  • _address_2 string - 辅助地址行(可选,可以是空字符串)。
  • _city string - 城市或城镇名称。
  • _state string - 州或省份代码。
  • _postcode string - 邮政编码。
  • _country string - 两位字母的国家/地区代码。

示例实现

/**
 * 自定义地址提供商客户端实现
 */
// 定义提供商
const customProvider = {
    // 必须与 PHP 提供商的 ID 匹配。
    id: 'custom-provider',

    /**
     * 检查提供商是否可以在给定国家/地区进行搜索
     *
     * @param {string} country - 两位字母的国家/地区代码(例如,'US'、'GB')
     * @return {boolean} 提供商是否支持该国家/地区
     */
    canSearch: function (country) {
      // 定义支持的国家/地区。
      const supportedCountries = ['US', 'CA', 'GB', 'AU'];
      return supportedCountries.includes(country);
    },

    /**
     * 搜索地址建议
     *
     * @param {string} query - 用户输入的搜索查询
     * @param {string} country - 选择的国家/地区代码
     * @param {string} type - 地址类型('billing' 或 'shipping')
     * @return {Promise<Array>} 建议对象的数组
     */
    search: async function (query, country, type) {
      // 返回搜索结果。 您的函数可能调用一个端点来获取这些数据。
      const data = [
        {
          id: '1',
          label: '123 Main Street, City, US',
          matchedSubstrings: [{ offset: 0, length: 3 }],
        },
        {
          id: '2',
          label: '456 Oak Avenue, Town, US',
          matchedSubstrings: [{ offset: 0, length: 3 }],
        },
        {
          id: '3',
          label: '789 Pine Road, Village, US',
          matchedSubstrings: [{ offset: 0, length: 3 }],
        },
        {
          id: '4',
          label: '101 Pine Road, Village, US',
          matchedSubstrings: [{ offset: 0, length: 3 }],
        },
        {
          id: '5',
          label: '101 Pine Road, Village, US',
          matchedSubstrings: [{ offset: 0, length: 3 }],
        },
      ];
      return data;
    },

    /**
     * 获取所选建议的完整地址详情
     *
     * @param {string} addressId - 所选建议的 ID
     * @return {Promise<Object>} 地址详情对象
     */
    select: async function (addressId) {
      // 返回地址组件,格式正确。 您的函数可能调用一个端点来获取这些数据。
      return {
        // 必需的字段
        address_1: 'Test address 1',
        city: 'Test City',
        state: 'CA',
        postcode: '92010',
        country: 'US',
      };
    },
  };

// 注册提供商。
if (
  window.wc &&
  window.wc.addressAutocomplete &&
  window.wc.addressAutocomplete.registerAddressAutocompleteProvider
) {
  window.wc.addressAutocomplete.registerAddressAutocompleteProvider(customProvider);
}

第 4 步:加载 JavaScript

在结账页面加载您的 JavaScript 文件。

即使未将您的服务提供商选择为首选服务提供商,也应加载此 JavaScript 文件。 这是因为,如果首选服务提供商无法搜索结果,您的服务提供商可以作为备用方案。

/**
 * 加载自定义服务提供商脚本
 */
function enqueue_custom_provider_scripts() {
    // 仅在结账页面加载
    if ( is_checkout() ) {
        // 检查是否启用了地址自动完成功能
        $is_enabled = get_option( 'woocommerce_address_autocomplete_enabled' ) === 'yes';
        
        if ( $is_enabled ) {
            wp_enqueue_script(
                'custom-address-provider',
                plugin_dir_url( __FILE__ ) . 'assets/js/custom-address-provider.js',
                array( 'wc-address-autocomplete' ),
                '1.0.0',
                true
            );
            
            // 将数据传递给 JavaScript
            wp_localize_script(
                'custom-address-provider',
                'yourPlugin',
                array(
                    'nonce' => wp_create_nonce( 'wp_rest' ),
                    'apiUrl' => rest_url( 'your-plugin/v1/' )
                )
            );
        }
    }
}
add_action( 'wp_enqueue_scripts', 'enqueue_custom_provider_scripts' );

REST API 实现

JavaScript 服务提供商通过 REST API 端点与您的服务器进行通信。 您需要创建两个端点:

  1. 地址搜索端点 (/wp-json/your-plugin/v1/address-search)

    • 接受:查询字符串,国家/地区代码,地址类型
    • 返回:包含 ID 和标签的建议数组
  2. 地址详情端点 (/wp-json/your-plugin/v1/address-details)

    • 接受:地址/地点 ID
    • 返回:完整的地址组件

有关实现详情,请参阅 WordPress REST API 手册。

故障排除

常见问题

  1. 服务提供商未在结账页面显示

    • 验证服务提供商是否已在服务器上注册
    • 检查 JavaScript 文件是否已加载
    • 确保 PHP 和 JavaScript 之间的服务提供商 ID 匹配
  2. 未显示建议

    • 检查浏览器控制台中的 JavaScript 错误
    • 验证 API 端点是否可访问
    • 检查国家/地区是否受服务提供商支持
    • 确保搜索查询至少包含 3 个字符
  3. 选择后字段未填充

    • 验证 select 方法是否返回正确的字段名称
    • 检查地址数据是否与 WooCommerce 字段结构匹配