# Architecture

## Plugin bootstrap

`globale-cross-border-for-woocommerce.php` is the sole WordPress plugin entry point. It:

1. Defines the constant `GCBWC_GLOBALE_PRO_FILE` pointing to itself.
2. Requires `includes/GlobaleProAutoloader.php` (PSR-0-style autoloader, PHP ≥ 5.6).
3. Reads the plugin header's `Version` field and stores it in `GCBWC_GLOBALE_PRO_VERSION`.
4. Instantiates the root class `GCBWC`, whose constructor hooks `GCBWC::init()` onto `plugins_loaded`.

### `GCBWC::init()`

Runs after all plugins are loaded. If `WC_Integration` exists (WooCommerce active):

- Includes `GlobaleProIntegration.php` and `woocommerce-globale-pro-functions.php`.
- Registers `GlobaleProIntegration` via the `woocommerce_integrations` filter.
- Declares HPOS compatibility via `FeaturesUtil::declare_compatibility('custom_order_tables', …, true)`.
- Calls `init_session()`, which hooks `GCBWC::woocommerce_loaded()` on `woocommerce_init` to handle session cookie quirks caused by the `qwc_set_cart_cookies` action (qtranslate-xt compatibility).

## Autoloader

`includes/GlobaleProAutoloader.php` maps the `GCBWC\` namespace root to the `includes/` directory, converting namespace separators to directory separators. No Composer autoloading is used at runtime; `composer.json` is present only for development tooling (PHPCS, PHPStan).

## WooCommerce integration class

`GlobaleProIntegration extends \WC_Integration` provides:

- **Settings form** (`init_form_fields`) — see [configuration.md](configuration.md).
- **Option persistence** (`process_admin_options`) — bypasses WooCommerce's standard sanitisation for raw JavaScript textarea fields (GA4, Facebook Pixel, TikTok Pixel, checkout JS code) to prevent double-escaping.
- **Frontend asset loading** (`enqueueScriptsAndStyles`) — enqueues the GEM/PRO JS and CSS from the configured GEPI base URL; on checkout pages additionally loads `checkout.js` and any configured analytics inline scripts.

## `GlobalePro` — request router

`includes/GlobalePro.php` wires all WooCommerce API callbacks at `woocommerce_init`:

```
woocommerce_api_pro-cart-info            → GlobalePro::apiCartInfo
woocommerce_api_pro-cart-clear           → GlobalePro::apiCartClear
woocommerce_api_pro-order-create-update  → GlobalePro::apiUpdateCreate
woocommerce_api_pro-order-payment        → GlobalePro::apiOrderPayment
woocommerce_api_pro-order-status         → GlobalePro::apiOrderStatus
woocommerce_api_pro-order-shipping       → GlobalePro::apiOrderShipping
woocommerce_api_pro-order-refund         → GlobalePro::apiOrderRefund
woocommerce_api_pro-validate-cart-voucher → GlobalePro::apiValidateCartVoucher
woocommerce_api_pro-plugin-info          → GlobalePro::apiPluginInfo
```

Additional late-binding hooks (also in `GlobalePro`):

| Hook | Purpose |
|---|---|
| `woocommerce_after_product_object_save` | Calls `ProductSaveHandler::handle()` to push product data to Global-e on save |
| `wc_price_based_country_before_frontend_init` | Pre-sets customer country from Global-e cookie for the WCPBC plugin |
| `wp_loaded` / `woocommerce_loaded` | `initAfterWc()` — clears cart and sets cart cookie for non-admin, non-REST pages |
| `woocommerce_set_cart_cookies` (priority 20) | `initAfterWcSetCookie()` — ensures cart cookie is set on Global-e REST calls |
| `wp_logout` | `Session::logout()` |
| `woocommerce_is_rest_api_request` | `isRestApi()` filter |

## Request detection

`GlobalePro` uses three detection methods to classify incoming requests:

- **`isRestApi()`** — `REST_REQUEST` constant, `rest_route` query param, or URL prefix match.
- **`isGlobaleRestApi()`** — URL contains `wc-api` **and** a `hash` query param or a JSON body with `CartId`.
- **`isSessionApi()`** — URL contains `wc-api`, no `hash`, endpoint is `pro-cart-info` or `pro-cart-clear`, and a WooCommerce session cookie is present.

## HPOS compatibility

The plugin explicitly declares HPOS (High-Performance Order Storage) compatibility. `Helper\Data` abstracts order meta reads/writes so they work with both the legacy `_postmeta` table and HPOS's custom order tables.

## Directory map

```
globale-cross-border-for-woocommerce/
├── globale-cross-border-for-woocommerce.php   ← plugin entry point
├── readme.txt
├── composer.json
├── phpcs.xml
├── phpstan.neon
├── includes/
│   ├── GlobaleProAutoloader.php
│   ├── GlobalePro.php
│   ├── GlobaleProInstall.php
│   ├── GlobaleProIntegration.php
│   ├── Config.php
│   ├── woocommerce-globale-pro-functions.php
│   ├── Admin/
│   │   ├── Order.php                  ← admin meta box for Global-e order data
│   │   └── ProductSaveHandler.php     ← triggers SaveProductList API on product save
│   ├── Api/
│   │   ├── Api.php                    ← base class (sendResponse, getRequestData)
│   │   ├── ApiParams.php
│   │   ├── App.php
│   │   ├── Cart.php
│   │   ├── Order.php
│   │   ├── PluginInfo.php
│   │   ├── ValidateCartVoucher.php
│   │   ├── Entity/                    ← data transfer objects
│   │   └── Processors/                ← AppSettings, SaveProductList
│   ├── Helper/
│   │   ├── Cookie.php
│   │   ├── Data.php
│   │   ├── Price.php
│   │   ├── RequestHelper.php
│   │   └── Session.php
│   ├── Model/
│   │   ├── Cart.php
│   │   ├── CartItemIdHelper.php
│   │   ├── Order.php
│   │   ├── Product.php
│   │   └── Order/
│   │       ├── Item.php
│   │       ├── Refund.php
│   │       └── Status.php
│   └── Front/
│       └── Cart.php                   ← coupon-removal on country switch
├── assets/
│   ├── js/frontend/
│   │   ├── pro.js
│   │   ├── gem.js
│   │   └── checkout.js
│   └── css/
├── examples/                          ← sample hook callback implementations
└── ai-docs/                           ← this corpus
```
