# CEP Autofill for WooCommerce Fills the WooCommerce checkout address from the CEP the shopper types. Street, neighbourhood, city and state, from official Correios data (DNE) via the [public API at cep.is](https://cep.is). Works on **both** WooCommerce checkouts — the Cart/Checkout Blocks and the classic `[woocommerce_checkout]` shortcode — see [Supported checkouts](#supported-checkouts). No Composer, no npm, no build step: the PHP client and the JavaScript widget are bundled in the plugin. ## Install Download the `.zip` from `dist/` (or run `make build`), then **Plugins → Add New → Upload Plugin** in WordPress. Activate it; WooCommerce must be active first. By default the shopper's browser talks to cep.is directly, so there is nothing to configure and no key to obtain. Requires WordPress 6.9 or newer, PHP 8.1 or newer, and WooCommerce. ## Settings **WooCommerce → Settings → CEP autofill.** | setting | default | what it does | | -------------------------- | -------- | ----------------------------------------------------------------------------------- | | **Autofill** | on | look the address up while the shopper types | | **Lookups go through** | browser | the browser straight to cep.is, or this site's REST API | | **Fields already filled** | keep | keep what the shopper typed / only fill empty fields / always overwrite | | **House number** | on | move the cursor to the house-number field after a hit (classic checkout) | | **API address** | cep.is | point at your own instance of the API | ### Lookups go through **The browser (default).** One cross-origin GET against a Cloudflare edge cache. No PHP runs, nothing is billed to the store, and the answer arrives in about twenty milliseconds. **This site.** The browser calls `/wp-json/cepis/v1/lookup/{token}/{cep}` instead, and PHP calls cep.is through `wp_remote_get()`. Choose this when a Content-Security-Policy on the checkout forbids external requests, or when you want the answers cached server-side. Answers are kept in transients: a hit for a week, since the database behind the API is regenerated fortnightly and a week is half a refresh cycle; a "does not exist" for a day, since a CEP absent today can appear in the next release. The route carries a short-lived token derived from the site's salts, and answers `403` without one. It is registered only while this mode is on. ### Fields already filled in `keep` — the default — fills empty fields, replaces values this plugin wrote itself, and leaves anything the shopper typed alone, so correcting a street by hand survives the next CEP. The state is the exception and is always replaced: the CEP decides it, and WooCommerce pre-selects the store's own state on a fresh checkout. ## Supported checkouts Both, and both verified in a real browser against a real store. | checkout | supported | how | | ---------------------------------------------- | --------- | --------------------------------------------------------------------------- | | **Cart/Checkout Blocks** (the default since WooCommerce 8.3) | yes | reads and writes the `wc/store/cart` data store; no DOM is touched | | **Classic** `[woocommerce_checkout]` | yes | the widget fills the fields directly and announces progress in an `aria-live` region | On the block checkout the fields are React-controlled, so the plugin drives the official `setShippingAddress` / `setBillingAddress` actions and reports failures through the checkout's own notice area. On the classic checkout the status message appears under the CEP field, styleable through `.cepis-autofill-status[data-cepis-state="…"]`. Both fill billing and shipping. The cart block's shipping calculator is not covered. Verified on WordPress 7.0.2, WooCommerce 10.9.4, PHP 8.3. `Requires at least` is declared as 6.9 because that is what WooCommerce 10.x itself requires; older WordPress was not tested. ## Brazilian address fields WooCommerce has no house-number and no neighbourhood field. When [Brazilian Market on WooCommerce](https://wordpress.org/plugins/woocommerce-extra-checkout-fields-for-brazil/) adds `billing_number` and `billing_neighborhood` to the classic checkout, this plugin fills the neighbourhood and moves the cursor to the number. When they are absent it fills what exists and does nothing else — the neighbourhood is **not** written into `address_2`, which in WooCommerce means "apartment, suite, unit" and would produce a wrong shipping label. The block checkout has no such fields and no plugin currently adds them. A store that registers its own with `woocommerce_register_additional_checkout_field()` can map it: ```php add_filter( 'cepis_woocommerce_blocks_fields', function ( $fields ) { $fields['bairro'] = 'my-plugin/neighborhood'; return $fields; } ); ``` The classic equivalent is `cepis_woocommerce_classic_fields`, which takes CSS selectors per address section, for themes and one-page-checkout plugins that rename the fields. `cepis_woocommerce_messages` overrides what the shopper is told. ## Development ```sh make # list the targets make test # stand a store up in Docker and drive the checkout in Chromium make lint # php -l, prettier --check, and phpcs when installed make format # apply prettier (writes) make build # produce dist/cepis-woocommerce-0.1.0.zip make check # lint, then test, then build make clean # remove build output and throw the test containers away ``` `make test` needs Docker and `bun`. It brings up WordPress, MySQL and WP-CLI from `test/compose.yml`, installs and configures WooCommerce, and drives both checkouts with Playwright's Chromium against a fake cep.is on the host, so no test touches the network. Install Chromium with `bunx playwright install chromium`, or point `CEPIS_CHROMIUM` at an existing binary. `make phpcs` fetches PHP_CodeSniffer and the WordPress standard into `.phpcs/`; `make lint` picks them up automatically once they are there. ### Refreshing the bundled dependencies `lib/cepis/` is the [PHP client](https://cep.is) and `assets/js/cepis-autofill.min.js` is the [autofill widget](https://cep.is), both copied in rather than installed, because a WordPress site is deployed by copying files and never runs `composer install`. ```sh tools/update-vendor.sh ../cepis-php ../cepis-autofill ``` That rebuilds the widget, copies both in, and leaves you a diff to review. ## Licence ISC. See [LICENSE](LICENSE).