# WooCommerce Plugin

The WooCommerce plugin is a merchant-side client. It does not talk to the processor directly.

## Responsibilities

- Register a WooCommerce payment gateway.
- Register the gateway for WooCommerce Checkout Blocks.
- Collect the WooCommerce order payload.
- Send the order to the Payment Gateway API.
- Render secure Payment Element fields directly inside the WooCommerce Checkout Block when inline mode is enabled.
- Render a merchant-hosted Payment Element page or redirect the customer to hosted checkout as fallback modes.
- Receive signed platform callbacks.
- Mark WooCommerce orders paid, failed, or cancelled.
- Report fulfillment, tracking, and late-shipment events to Payment Gateway for compliance monitoring.

## Merchant Settings

In WooCommerce:

```text
WooCommerce -> Settings -> Payments -> Payment Gateway
```

The merchant configures:

```text
Payment Gateway API Base URL
Payment Gateway Merchant Token
Checkout title
Checkout description
Fulfillment reporting toggle
Late shipment warning and critical thresholds
Checkout experience: Inline card fields, Payment Element page fallback, or Hosted redirect
```

After entering credentials, the merchant should click:

```text
Test Payment Gateway connection
```

The test validates:

```text
merchant token
connected processor account readiness
card payment and transfer capabilities
WooCommerce callback URL delivery
Apple Pay / Google Pay payment-method domain registration
```

The connection test sends the merchant's WordPress site URL to the platform. The platform registers that domain against the merchant connected account so wallet buttons can render when the browser, device, wallet, currency, HTTPS configuration, and processor settings are eligible.

## Fulfillment Monitoring

The plugin reports fulfillment events for gateway-paid physical orders.

Tracked sources:

```text
WooCommerce Shipment Tracking: _wc_shipment_tracking_items
Advanced Shipment Tracking: ast_get_tracking_items and AST tracking meta
Shipmate: _shipmate_carrier, _shipmate_service, _shipmate_tracking_reference
AfterShip: AfterShip tracking meta
ShipStation and carrier plugins: known tracking-number meta keys
Generic fallback: scalar order meta keys containing tracking/shipment/carrier plugin names
```

Triggers:

```text
payment succeeded callback
WooCommerce order status changes
order save events
tracking plugin hooks
tracking meta updates
hourly late-shipment scanner
```

Compliance timing:

```text
48 hours after payment with no shipment evidence: warning
72 hours after payment with no shipment evidence: critical
```

The plugin does not treat `completed` alone as proof of shipment. Tracking numbers or explicit shipped/partially-shipped statuses are stronger shipment evidence.

The merchant does not configure:

```text
processor API keys
processor webhook secrets
Platform fee rates
Connected account routing logic
Platform publishable key
```

## Inline Checkout Blocks

Plugin version `4.0.0` supports inline card fields inside the modern WooCommerce Checkout Block.

When enabled, the block creates a pre-order PaymentIntent from the current WooCommerce cart:

```text
POST /wp-json/payment-gateway/v1/inline-payment-intent
```

The plugin sends that cart payload to:

```text
POST /payment-intents
```

The platform returns a client secret, publishable key, connected account ID, and PaymentIntent ID. The block mounts Stripe Payment Element inside checkout. When the customer clicks Place order, WooCommerce Blocks confirms the PaymentIntent first, then sends the confirmed `payment_intent_id`, `client_secret`, and stable `checkout_id` into the normal WooCommerce order creation flow.

After WooCommerce creates the real order, the plugin calls:

```text
POST /payment-intents/{payment_intent_id}/reconcile
```

The platform accepts the final WooCommerce order ID when it matches the original `checkout_id`, and the plugin marks the order paid if the PaymentIntent succeeded.

Inline mode requires the WooCommerce Checkout Block. If the merchant is using the legacy shortcode checkout or a custom checkout plugin that does not run WooCommerce Blocks payment setup, the plugin falls back to the merchant-hosted Payment Element page.

## Payment Element Page

Plugin version `4.0.0` still supports an optional `Payment Element page fallback` checkout experience.

When enabled, WooCommerce sends the order to:

```text
POST /payment-intents
```

The platform returns a PaymentIntent client secret, publishable key, and connected account ID. The plugin then redirects the customer to a merchant-hosted payment page and mounts Payment Element there.

This fallback is not the same as inline Checkout Blocks. WooCommerce creates the order first, then the plugin creates the PaymentIntent, then the customer enters payment details on the merchant-hosted payment page.

Apple Pay and Google Pay can still work. They are not hardcoded by the plugin; the processor shows them when the payment method is enabled, the merchant domain is registered and served over HTTPS, and the customer's browser/device/wallet/currency is eligible. If no wallet is eligible, the normal Payment Element remains available.

The public plugin ZIP does not include a merchant token. If a token appears after reinstalling the plugin, WordPress is loading previously saved WooCommerce gateway settings from `wp_options`. Delete the plugin through WordPress to run `uninstall.php`, or clear the `woocommerce_payment_gateway_settings` option before reinstalling.

## Callback Endpoint

Each merchant site exposes:

```text
/wp-json/payment-gateway/v1/callback
```

Use `wp-json`, not `wp-jsn`. A `wp-jsn` URL is a normal WordPress 404 and will leave paid orders pending because Payment Gateway cannot deliver the signed payment callback.

The Payment Gateway API signs callback bodies with the merchant token hash.

The plugin verifies:

```text
X-Platform-Signature
```

Signature method:

```text
hmac_sha256(raw_json_body, sha256(merchant_api_token))
```

## Checkout Flow

1. Customer chooses Payment Gateway.
2. In inline mode, the Checkout Block creates a cart-based PaymentIntent before order creation.
3. Customer enters payment details inside WooCommerce checkout and clicks Place order.
4. WooCommerce creates the order and sends the confirmed PaymentIntent ID to the plugin.
5. Plugin reconciles the PaymentIntent against the real WooCommerce order.
6. Processor sends webhook to the Payment Gateway API.
7. Payment Gateway API sends signed callback to the merchant site.
8. Plugin updates the WooCommerce order.
